HDU 3397 线段树 较麻烦

来源:互联网 发布:sql查询例子 编辑:程序博客网 时间:2024/04/30 03:43

3911的升级版

同时要做两种LAZY操作,一定要先做COVER,否则会WA,因为COVER可以覆盖之前的XOR

 

#include "stdio.h"#include "string.h"#include "math.h"#include "stdlib.h"#include "algorithm"using namespace std;struct comp{    int l,r,mid;    int l1,l0; // 记录区间内从最左端起连续1和0个数    int r1,r0; // 记录区间内从最右端起连续1和0个数    int m1,m0; // 记录区间内最长连续1和0个数    int cover; // lazy操作的覆盖    int xor; // lazy操作的变换    int sum; // 区间内1的总数} data[300005];int max(int a,int b){    if (a<b) return b; else return a;}void PushUp(int k){    int ll,rr;    ll=data[k*2].r-data[k*2].l+1;    rr=data[k*2+1].r-data[k*2+1].l+1;    data[k].sum=data[k*2].sum+data[k*2+1].sum;    data[k].l1=data[k*2].l1;    if (data[k].l1==ll) data[k].l1+=data[k*2+1].l1;    data[k].l0=data[k*2].l0;    if (data[k].l0==ll) data[k].l0+=data[k*2+1].l0;    data[k].r1=data[k*2+1].r1;    if (data[k].r1==rr) data[k].r1+=data[k*2].r1;    data[k].r0=data[k*2+1].r0;    if (data[k].r0==rr) data[k].r0+=data[k*2].r0;    data[k].m1=max(  max(data[k*2].m1,data[k*2+1].m1) ,  data[k*2].r1+data[k*2+1].l1);    data[k].m0=max(  max(data[k*2].m0,data[k*2+1].m0) ,  data[k*2].r0+data[k*2+1].l0);}void build(int l,int r,int k){    int x;    data[k].l=l; data[k].r=r;    data[k].mid=(l+r)/2;    data[k].xor=0;    data[k].cover=-1;        if (l==r)    {        scanf("%d",&x);        if (x==1)        {            data[k].l1=data[k].r1=data[k].m1=1;            data[k].l0=data[k].r0=data[k].m0=0;            data[k].sum=1;            data[k].cover=1;        }        else         {            data[k].l1=data[k].r1=data[k].m1=0;            data[k].l0=data[k].r0=data[k].m0=1;            data[k].sum=0;            data[k].cover=0;        }        return ;    }    build(l,data[k].mid,k*2);    build(data[k].mid+1,r,k*2+1);    PushUp(k);}void PushDown(int k) // 重点是两种LAZY操作的顺序,必须先做COVER操作{    int ll,rr;    if (data[k].l==data[k].r) return ;    ll=data[k*2].r-data[k*2].l+1;    rr=data[k*2+1].r-data[k*2+1].l+1;    if (data[k].cover!=-1)    {        data[k*2].cover=data[k*2+1].cover=data[k].cover;        data[k*2].xor=data[k*2+1].xor=0;        if (data[k].cover==1)        {            data[k*2].sum=ll;            data[k*2+1].sum=rr;                        data[k*2].l1=data[k*2].r1=data[k*2].m1=ll;            data[k*2].l0=data[k*2].r0=data[k*2].m0=0;            data[k*2+1].l1=data[k*2+1].r1=data[k*2+1].m1=rr;            data[k*2+1].l0=data[k*2+1].r0=data[k*2+1].m0=0;        }        if (data[k].cover==0)        {            data[k*2].sum=data[k*2+1].sum=0;            data[k*2].l1=data[k*2].r1=data[k*2].m1=0;            data[k*2].l0=data[k*2].r0=data[k*2].m0=ll;            data[k*2+1].l1=data[k*2+1].r1=data[k*2+1].m1=0;            data[k*2+1].l0=data[k*2+1].r0=data[k*2+1].m0=rr;        }        data[k].cover=-1;    }if (data[k].xor%2==1)    {        data[k].xor=0;        data[k*2].xor++;        data[k*2+1].xor++;        data[k*2].sum=ll-data[k*2].sum;        data[k*2+1].sum=rr-data[k*2+1].sum;        swap(data[k*2].l1,data[k*2].l0);        swap(data[k*2].r1,data[k*2].r0);        swap(data[k*2].m1,data[k*2].m0);        swap(data[k*2+1].l1,data[k*2+1].l0);        swap(data[k*2+1].r1,data[k*2+1].r0);        swap(data[k*2+1].m1,data[k*2+1].m0);    }    }    void update(int l,int r,int k,int op){    int le;    PushDown(k);    if (data[k].l==l && data[k].r==r )    {        le=data[k].r-data[k].l+1;        if (op==0)        {            data[k].cover=0;            data[k].sum=0;            data[k].l1=data[k].r1=data[k].m1=0;            data[k].l0=data[k].r0=data[k].m0=le;            data[k].xor=0;        }        if (op==1)        {            data[k].cover=1;            data[k].sum=le;            data[k].l1=data[k].r1=data[k].m1=le;            data[k].l0=data[k].r0=data[k].m0=0;            data[k].xor=0;        }        if (op==2)        {            if (data[k].cover!=-1) data[k].cover=(data[k].cover+1)%2;            data[k].sum=le-data[k].sum;            swap(data[k].l1,data[k].l0);            swap(data[k].r1,data[k].r0);            swap(data[k].m1,data[k].m0);            data[k].xor++;        }        return ;    }        if (r<=data[k].mid) update(l,r,k*2,op);    else         if (l>data[k].mid) update(l,r,k*2+1,op);        else         {            update(l,data[k].mid,k*2,op);            update(data[k].mid+1,r,k*2+1,op);        }    PushUp(k);}int query(int l,int r,int k,int op){    int aa,bb,ll,rr;    if (data[k].l==l && data[k].r==r)     {        if (op==3) return data[k].sum;        else return data[k].m1;    }    PushDown(k);    if (r<=data[k].mid) return query(l,r,k*2,op);    else         if (l>data[k].mid) return query(l,r,k*2+1,op);        else         {            if (op==3) return query(l,data[k].mid,k*2,op)+query(data[k].mid+1,r,k*2+1,op);            else             {                aa=query(l,data[k].mid,k*2,op);                bb=query(data[k].mid+1,r,k*2+1,op);                ll=data[k*2].r1;                if (ll>data[k*2].r-l+1) ll=data[k*2].r-l+1;                rr=data[k*2+1].l1;                if (rr>r-data[k*2+1].l+1) rr=r-data[k*2+1].l+1;                return max(max(aa,bb),ll+rr);            }        }}int main(){    int t,n,m,a,b,c;    scanf("%d",&t);    while (t--)    {        scanf("%d%d",&n,&m);        build(1,n,1);        while (m--)        {            scanf("%d%d%d",&a,&b,&c);            b++;            c++;            if (a<=2) update(b,c,1,a);            else                     printf("%d\n",query(b,c,1,a));        }    }    return 0;}


 

原创粉丝点击