30ptsRE求条玄关
查看原帖
30ptsRE求条玄关
640816
cengzh楼主2024/10/20 23:52
# include <stdio.h>
# include <iostream>

using namespace std;

struct Tree
{
    int n; // naodong
    int l,r;
    int f[2][2];
};

struct Tree t[200005*4];
int tag[200005*4]; // 1 -> 0 2 -> 1

void add_tag(int node,int l,int r,int w)
{
    tag[node] = w;
    t[node].l = t[node].r = w-1;
    t[node].n = (r-l+1) * (w-1);
    t[node].f[1][1] = (r-l+1) * ((w-1)^1);
    t[node].f[0][1] = t[node].f[1][0] = (r-l) * ((w-1)^1);
    if (r - l - 1 < 0)
    {
        t[node].f[0][0] = 0;
    }
    else
    {
        t[node].f[0][0] = (r-l-1) * ((w-1)^1);
    }

    return ;
}

void push_up(int node,int l,int r)
{
    t[node].n = t[node*2].n + t[node*2+1].n;
    t[node].l = t[node*2].l;
    t[node].r = t[node*2+1].r;

    t[node].f[0][0] = max(t[node*2].f[0][1],max(t[node*2].f[0][0],max(t[node*2+1].f[0][0],t[node*2+1].f[1][0])));
    t[node].f[0][1] = max(t[node*2+1].f[0][1],t[node*2+1].f[1][1]);
    t[node].f[1][0] = max(t[node*2].f[1][0],t[node*2].f[1][1]);

    if (t[node].n != 0)
    {
        t[node].f[1][1] = 0;
    }
    else
    {
        t[node].f[1][1] = r-l+1;
    }

    if (t[node*2].r == 0 && t[node*2+1].l == 0)
    {
        t[node].f[0][0] = max(t[node].f[0][0],t[node*2].f[0][1]+t[node*2+1].f[1][0]);

    }
    if (t[node*2].f[1][1] != 0)
    {

        t[node].f[1][0] = max(t[node].f[1][0],t[node*2].f[1][1]+t[node*2+1].f[1][0]);
    }
    if (t[node*2+1].f[1][1] != 0)
    {
        t[node].f[0][1] = max(t[node].f[0][1],t[node*2].f[0][1]+t[node*2+1].f[1][1]);
    }
    return ;
}

void push_down(int node,int l,int r,int mid)
{
    if (tag[node] != 0)
    {
        add_tag(node*2,l,mid,tag[node]);
        add_tag(node*2+1,mid+1,r,tag[node]);
        tag[node] = 0;
    }
    return ;
}

void build(int node,int l,int r)
{
    if (l == r)
    {
        t[node].n = t[node].l = t[node].r = 1;
        t[node].f[0][0] = t[node].f[1][0] = t[node].f[0][1] = t[node].f[1][1] = 0;
        return ;
    }

    int mid = (l+r)/2;

    build(node*2,l,mid);
    build(node*2+1,mid+1,r);

    push_up(node,l,r);

    return ;
}

int update1(int node,int l,int r,int tl,int tr) // 1 -> 0
{
    int res = 0;
    if (tl <= l && r <= tr)
    {
        res = t[node].n;
        add_tag(node,l,r,1);
      //  printf ("[l,r]:[%d,%d] n:%d f[0][0]:%d f[0][1]:%d f[1][0]:%d f[1][1]:%d\n",l,r,t[node].n,t[node].f[0][0],t[node].f[0][1],t[node].f[1][0],t[node].f[1][1]);

        return res;
    }

    int mid = (l+r)/2;

    push_down(node,l,r,mid);

    if (mid >= tl)
    {
        res += update1(node*2,l,mid,tl,tr);
    }
    if (mid < tr)
    {
        res += update1(node*2+1,mid+1,r,tl,tr);
    }

    push_up(node,l,r);


    return res;
}

void bu(int node,int l,int r,int tl,int tr,int w)
{
    if (tl <= l && r <= tr && w >= (r-l+1) - t[node].n)
    {
        add_tag(node,l,r,2);
        return;
    }

    int mid = (l+r) / 2;

    push_down(node,l,r,mid);
    int c1=0,c2=0;

    if (mid >= tl)
    {
        if (w > (mid-l+1))
        {
            bu(node*2,l,mid,tl,tr,mid-l+1);
        }
        else
        {
            bu(node*2,l,mid,tl,tr,w);
        }
        c1=1;
    }
    if (mid < tr)
    {
        if (w > (mid-l+1))
        {
            bu(node*2+1,mid+1,r,tl,tr,w-(mid-l+1));
        }
        else if (!c1)
        {
            bu(node*2+1,mid+1,r,tl,tr,w-(mid-l+1));
        }
    }
    push_up(node,l,r);
    return ;
}

struct Tree query(int node,int l,int r,int tl,int tr)
{
    if (tl <= l && r <= tr)
    {
        return t[node];
    }

    int mid = (l+r)/2;
    push_down(node,l,r,mid);
    struct Tree t1,t2,t3;
    int c1=0,c2=0;

    if (mid >= tl)
    {
        t1 = query(node*2,l,mid,tl,tr);
        c1=1;
    }
    if (mid < tr)
    {
        t2 = query(node*2+1,mid+1,r,tl,tr);
        c2 = 1;
    }

    if (c1 && c2)
    {
        t3.n = t1.n + t2.n;
        t3.l = t1.l;
        t3.r = t2.r;

        t3.f[0][0] = max(t1.f[0][1],max(t1.f[0][0],max(t2.f[0][0],t2.f[1][0])));
        t3.f[0][1] = max(t2.f[0][1],t2.f[1][1]);
        t3.f[1][0] = max(t1.f[1][0],t1.f[1][1]);
        t3.f[1][1] = 0;

        if (t[node*2].r == 0 && t[node*2+1].l == 0)
        {
            t3.f[0][0] = max(t3.f[0][0],t1.f[0][1]+t2.f[1][0]);
            t3.f[0][1] = max(t3.f[0][1],t1.f[0][1]+t2.f[1][1]);
            t3.f[1][0] = max(t3.f[1][0],t1.f[1][1]+t2.f[1][0]);
            t3.f[1][1] = max(t3.f[1][1],t1.f[1][1]+t2.f[1][1]);
        }
    }
    else if (c1)
    {
        t3 = t1;
    }
    else
    {
        t3 = t2;
    }

    return t3;
}

int main (void)
{
    int n,m;
    scanf ("%d %d",&n,&m);

    build(1,1,n);
    int l,r,l0,r0,l1,r1;
    for (int i=0;i<m;i++)
    {
        int opt;
        scanf ("%d",&opt);
        if (opt == 0)
        {
            scanf ("%d %d",&l,&r);
            update1(1,1,n,l,r);
        }
        else if (opt == 1)
        {
            scanf ("%d %d %d %d",&l0,&r0,&l1,&r1);
            int res = update1(1,1,n,l0,r0);
            bu(1,1,n,l1,r1,res);
        }
        else if (opt == 2)
        {
            scanf ("%d %d",&l,&r);
            struct Tree temp = query(1,1,n,l,r);
            printf ("%d\n",max(temp.f[0][0],max(temp.f[1][0],max(temp.f[0][1],temp.f[1][1]))));

        }
    }

    return 0;
}

没看题解,自己写的,好像有点屎,hack可过,但不清楚为什么RE,大概是在n>=100000的情况下

2024/10/20 23:52
加载中...