线段树区间维护hdu3397

来源:互联网 发布:淘宝的销量多久清零 编辑:程序博客网 时间:2024/05/16 23:52

这个题维护的东西有点多,写恶心了,没调出来,过两天接着看

7.7样例终于过了,可还是wa。。。

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=100010;int n,m,a[maxn];struct IntervalTree{    int sum1[maxn<<3],cnt0[maxn<<3],cnt1[maxn<<3];    int r0[maxn<<3],r1[maxn<<3],l0[maxn<<3],l1[maxn<<3];    int setv[maxn<<3],XOR[maxn<<3];    void maintainXOR(int o,int l,int r)    {        sum1[o]=r-l+1-sum1[o];        swap(r0[o],r1[o]);        swap(l0[o],l1[o]);        swap(cnt0[o],cnt1[o]);    }    void maintain(int o,int l,int r)    {        if(setv[o]==0)        {            l0[o]=r0[o]=r-l+1;            sum1[o]=l1[o]=r1[o]=0;            cnt1[o]=0,cnt0[o]=r-l+1;        }        else if(setv[o]==1)        {            l0[o]=r0[o]=0;            l1[o]=r1[o]=r-l+1;            sum1[o]=cnt1[o]=r-l+1;            cnt0[o]=0;        }    }    void build(int o,int l,int r)    {        sum1[o]=r0[o]=r1[o]=l0[o]=l1[o]=cnt0[o]=cnt1[o]=0;        setv[o]=-1,XOR[o]=0,cnt1[o]=cnt0[o]=0;        if(l==r)        {            if(a[l]==1)            {                sum1[o]=cnt1[o]=1;                r1[o]=l1[o]=1;                cnt0[o]=0;                r0[o]=l0[o]=0;            }            else            {                sum1[o]=cnt1[o]=0;                r1[o]=l1[o]=0;                cnt0[o]=1;                r0[o]=l0[o]=1;            }            return;        }        int mid=(l+r)>>1;        build(o<<1,l,mid);        build(o<<1|1,mid+1,r);        pushup(o,l,r);    }    void pushdown(int o,int l,int r)    {        if(r<=l)return;        if(setv[o]!=-1)        {            setv[o<<1]=setv[o<<1|1]=setv[o];            XOR[o<<1]=XOR[o<<1|1]=0;            int mid=(l+r)>>1;            maintain(o<<1,l,mid);            maintain(o<<1|1,mid+1,r);            setv[o]=-1;        }        if(XOR[o])        {            XOR[o<<1]^=1;            XOR[o<<1|1]^=1;            XOR[o]=0;            int mid=(l+r)>>1;            maintainXOR(o<<1,l,mid);            maintainXOR(o<<1|1,mid+1,r);        }    }    void pushup(int o,int l,int r)    {        if(r<=l)return;        l0[o]=l0[o<<1],l1[o]=l1[o<<1];        r0[o]=r0[o<<1|1],r1[o]=r1[o<<1|1];        cnt0[o]=max(cnt0[o<<1],cnt0[o<<1|1]);        cnt1[o]=max(cnt1[o<<1],cnt1[o<<1|1]);        cnt0[o]=max(cnt0[o],r0[o<<1]+l0[o<<1|1]);        cnt1[o]=max(cnt1[o],r1[o<<1]+l1[o<<1|1]);        int mid=(l+r)>>1;        if(l0[o]==mid-l+1)l0[o]+=l0[o<<1|1];        if(l1[o]==mid-l+1)l1[o]+=l1[o<<1|1];        if(r0[o]==r-mid)r0[o]+=r0[o<<1];        if(r1[o]==r-mid)r1[o]+=r1[o<<1];        sum1[o]=sum1[o<<1]+sum1[o<<1|1];    }    void update(int o,int l,int r,int q1,int q2,int op)    {        pushdown(o,l,r);        if(q1<=l&&r<=q2)        {            if(op==2){XOR[o]=1;maintainXOR(o,l,r);}            else {setv[o]=op;maintain(o,l,r);}            return;        }        int mid=(l+r)>>1;        if(q1<=mid)update(o<<1,l,mid,q1,q2,op);//else maintain(o<<1,l,mid);        if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,op);//else maintain(o<<1|1,mid+1,r);        pushup(o,l,r);    }    int query(int o,int l,int r,int q1,int q2,int op)    {        pushdown(o,l,r);        if(q1<=l&&r<=q2)        {            if(op==3)return sum1[o];            if(op==4)return cnt1[o];        }        int mid=(l+r)>>1;        int x=0,y=0;        if(q1<=mid)x=query(o<<1,l,mid,q1,q2,op);        if(q2>mid)y=query(o<<1|1,mid+1,r,q1,q2,op);        if(op==3)return x+y;        if(q1<=mid&&q2>mid)        {            x=max(x,y);            y=min(mid-q1+1,r1[o<<1])+min(q2-mid,l1[o<<1|1]);            x=max(x,y);        }        return x;    }}tree;int main(){    freopen("in.txt","r",stdin);    int T,x,y,op;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)scanf("%d",&a[i]);        tree.build(1,1,n);        while(m--)        {            scanf("%d%d%d",&op,&x,&y);            x++,y++;            if(op<=2)tree.update(1,1,n,x,y,op);            else printf("%d\n",tree.query(1,1,n,x,y,op));        }    }    return 0;}


下面是别人的代码:

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define lson u<<1#define rson u<<1|1#define MAXN 100010int dat[MAXN];struct Node {int lef,rig;int lsum,rsum,msum;//左端最长连续1,右端最长连续1,区间最长连续1int lz,rz,mz;//左端最长连续0,右端最长连续0,区间最长连续0int sum;//区间1的个数int COVER,XOR;}T[MAXN<<2];void makeXOR(int u){//翻转操作swap(T[u].lsum,T[u].lz);swap(T[u].rsum,T[u].rz);swap(T[u].msum,T[u].mz);T[u].sum=T[u].rig-T[u].lef+1-T[u].sum;}void PushUp(int u){if(T[u].lef==T[u].rig)return;int len=T[u].rig-T[u].lef+1;T[u].lsum=T[lson].lsum;T[u].rsum=T[rson].rsum;if(T[u].lsum==(len+1)>>1)T[u].lsum+=T[rson].lsum;if(T[u].rsum==len>>1)T[u].rsum+=T[lson].rsum;T[u].msum=max(T[lson].msum,T[rson].msum);T[u].msum=max(T[u].msum,T[lson].rsum+T[rson].lsum);T[u].lz=T[lson].lz;T[u].rz=T[rson].rz;if(T[u].lz==(len+1)>>1)T[u].lz+=T[rson].lz;if(T[u].rz==len>>1)T[u].rz+=T[lson].rz;T[u].mz=max(T[lson].mz,T[rson].mz);T[u].mz=max(T[u].mz,T[lson].rz+T[rson].lz);T[u].sum=T[lson].sum+T[rson].sum;}void PushDown(int u){if(T[u].lef==T[u].rig)return;if(T[u].COVER!=-1){int len=T[u].rig-T[u].lef+1;T[lson].COVER=T[rson].COVER=T[u].COVER;T[lson].XOR=T[rson].XOR=0;T[lson].lsum=T[lson].rsum=T[lson].msum=T[u].COVER?(len+1)>>1:0;T[lson].lz=T[lson].rz=T[lson].mz=T[u].COVER?0:(len+1)>>1;T[lson].sum=T[u].COVER?(len+1)>>1:0;T[rson].lsum=T[rson].rsum=T[rson].msum=T[u].COVER?len>>1:0;T[rson].lz=T[rson].rz=T[rson].mz=T[u].COVER?0:len>>1;T[rson].sum=T[u].COVER?len>>1:0;T[u].COVER=-1;}if(T[u].XOR){T[u].XOR=0;T[lson].XOR^=1;T[rson].XOR^=1;makeXOR(lson);makeXOR(rson);}}void Build(int u,int l,int r){T[u].lef=l;T[u].rig=r;T[u].COVER=-1;T[u].XOR=0;if(l==r){T[u].lsum=T[u].rsum=T[u].msum=(dat[l]==1);T[u].lz=T[u].rz=T[u].mz=(dat[l]==0);T[u].sum=dat[l];T[u].COVER=dat[l];return;}int mid=(l+r)>>1;Build(lson,l,mid);Build(rson,mid+1,r);PushUp(u);}void Update(int u,int l,int r,int op){PushDown(u);//这里应该先pushdownif(l<=T[u].lef&&T[u].rig<=r){if(op<2){//覆盖操作int len=T[u].rig-T[u].lef+1;T[u].COVER=op;T[u].lsum=T[u].rsum=T[u].msum=op?len:0;T[u].lz=T[u].rz=T[u].mz=op?0:len;T[u].sum=op?len:0;}else {T[u].XOR=1;makeXOR(u);}}else {if(l<=T[lson].rig)Update(lson,l,r,op);if(r>=T[rson].lef)Update(rson,l,r,op);PushUp(u);}}int Query(int u,int l,int r,int op){PushDown(u);//应该先 pushdown,以防错误if(l<=T[u].lef&&T[u].rig<=r){if(op==3)return T[u].sum;else return T[u].msum;}else {if(r<=T[lson].rig)return Query(lson,l,r,op);if(l>=T[rson].lef)return Query(rson,l,r,op);if(op==3) return Query(lson,l,T[lson].rig,op)+Query(rson,T[rson].lef,r,op);int ret=min(T[lson].rsum,T[lson].rig-l+1)+min(T[rson].lsum,r-T[rson].lef+1);int ans=max(Query(lson,l,T[lson].rig,op),Query(rson,T[rson].lef,r,op));return max(ans,ret);}}int main(){int t;scanf("%d",&t);while(t--){int n,m;int cmd,a,b;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",dat+i);Build(1,1,n);while(m--){scanf("%d%d%d",&cmd,&a,&b);a++,b++;if(cmd<3)Update(1,a,b,cmd);else printf("%d\n",Query(1,a,b,cmd));}}return 0;}


0 0