hdu3397 Sequence operation

     感觉自己好像搞定了一个不得了得题呢。。

    对于这种区间性质合并的线段树,对于每个节点保存一下当前区间内1的个数,左右边界相邻的1个的个数与0的个数,还有当前区间最大连续的1和0的个数.

    合并的时候的细节:

    1.如果lson的右边界是1并且rson的左边界是1,那么当前节点的最大连续1的值应该更新为tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);

    2.如果lson的连续1的个数等于它所表示的区间大小(这段区间的值全为1),那么当前节点的左区间连续1的个数应该更新为tr[n].l+=tr[RR].l;对于右区间的连续1的个数更新也一样。

    3.对于区间中0的性质更新与1一样

    更新时候的细节

    1.如果当前进行的是区间覆盖,那么是需要吧区间翻转的标记置0的。

    2.如果当前既需要更新区间覆盖与区间翻转,这时候只有一种可能情况就是区间覆盖是先进行赋值过的,所以在pushdown的时候区间覆盖应该先进行。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define LL n<<1
  4 #define RR n<<1|1
  5 #define lson l,mid,LL
  6 #define rson mid+1,r,RR
  7 #define mid ((l+r)/2)
  8 const int maxn=500005;
  9 struct node{
 10     int res,ret,num,l,r,ll,rr;//最长连续1的长度,最长连续0的长度,区间内1的个数,区间内左右边界连续1的个数,0的个数 
 11 };
 12 node tr[maxn<<2];
 13 int lazy[maxn<<2];//区间覆盖懒惰标记 
 14 int chan[maxn<<2];//区间翻转懒惰标记 
 15 int a[maxn];
 16 void up(int l,int r,int n){
 17     tr[n].num=tr[LL].num+tr[RR].num;
 18     tr[n].res=max(tr[LL].res,tr[RR].res);
 19     tr[n].ret=max(tr[LL].ret,tr[RR].ret);
 20     tr[n].l=tr[LL].l;
 21     tr[n].ll=tr[LL].ll;
 22     tr[n].r=tr[RR].r;
 23     tr[n].rr=tr[RR].rr;
 24     if(tr[LL].r&&tr[RR].l)
 25     {
 26         tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);
 27         if(mid-l+1==tr[LL].res)
 28         tr[n].l+=tr[RR].l;
 29         if(r-mid==tr[RR].res)
 30         tr[n].r+=tr[LL].r;
 31     }
 32     if(tr[LL].rr&&tr[RR].ll)
 33     {
 34         tr[n].ret=max(tr[n].ret,tr[LL].rr+tr[RR].ll);
 35         if(mid-l+1==tr[LL].ret)
 36         tr[n].ll+=tr[RR].ll;
 37         if(r-mid==tr[RR].ret)
 38         tr[n].rr+=tr[LL].rr;
 39     } 
 40 }
 41 void built(int l,int r,int n){
 42     lazy[n]=-1;
 43     chan[n]=0;
 44     if(l==r)
 45     {
 46         tr[n].l=tr[n].r=tr[n].res=tr[n].num=a[l];
 47         tr[n].ret=tr[n].ll=tr[n].rr=!a[l];
 48         return;
 49     }
 50     built(lson);
 51     built(rson);
 52     up(l,r,n);
 53 }
 54 void pushdown(int l,int r,int n){
 55     if(lazy[n]!=-1)
 56     {
 57         chan[LL]=chan[RR]=0;
 58         tr[LL].num=tr[LL].l=tr[LL].r=tr[LL].res=(mid-l+1)*lazy[n];
 59         tr[LL].ll=tr[LL].rr=tr[LL].ret=(mid-l+1)*(!lazy[n]);
 60         tr[RR].num=tr[RR].l=tr[RR].r=tr[RR].res=(r-mid)*lazy[n];
 61         tr[RR].ll=tr[RR].rr=tr[RR].ret=(r-mid)*(!lazy[n]);
 62         lazy[LL]=lazy[RR]=lazy[n];
 63         lazy[n]=-1;
 64     }
 65     if(chan[n])
 66     {
 67         chan[LL]^=1;
 68         chan[RR]^=1;
 69         tr[LL].num=mid-l+1-tr[LL].num;
 70         tr[RR].num=r-mid-tr[RR].num;
 71         swap(tr[LL].res,tr[LL].ret);
 72         swap(tr[LL].ll,tr[LL].l);
 73         swap(tr[LL].rr,tr[LL].r);
 74         swap(tr[RR].res,tr[RR].ret);
 75         swap(tr[RR].ll,tr[RR].l);
 76         swap(tr[RR].rr,tr[RR].r);
 77         chan[n]=0; 
 78     }
 79 }
 80 void update(int l,int r,int n,int left,int right,int num){
 81     if(l>=left&&right>=r)
 82     {
 83         lazy[n]=num;
 84         tr[n].num=num*(r-l+1);
 85         chan[n]=0;
 86         tr[n].l=tr[n].r=tr[n].res=(r-l+1)*num;
 87         tr[n].ll=tr[n].rr=tr[n].ret=(r-l+1)*(!num);
 88         return;
 89     }
 90     pushdown(l,r,n);
 91     if(left<=mid)
 92     update(lson,left,right,num);
 93     if(right>mid)
 94     update(rson,left,right,num);
 95     up(l,r,n);
 96 }
 97 void change(int l,int r,int n,int left,int right){
 98     if(l>=left&&right>=r)
 99     {
100         chan[n]^=1;
101         tr[n].num=(r-l+1-tr[n].num);
102         swap(tr[n].res,tr[n].ret);
103         swap(tr[n].ll,tr[n].l);
104         swap(tr[n].rr,tr[n].r);
105         return;
106     }
107     pushdown(l,r,n);
108     if(left<=mid)
109     change(lson,left,right);
110     if(right>mid)
111     change(rson,left,right);
112     up(l,r,n);
113 }
114 int out1(int l,int r,int n,int left,int right){
115     if(l>=left&&right>=r)
116     return tr[n].num;
117     pushdown(l,r,n);
118     int res=0;
119     if(left<=mid)
120     res+=out1(lson,left,right);
121     if(right>mid)
122     res+=out1(rson,left,right);
123     return res;
124 }
125 int out2(int l,int r,int n,int left,int right){
126     if(l>=left&&right>=r)
127     return tr[n].res;
128     pushdown(l,r,n);
129     int res=0;
130     if(left<=mid)
131     res=max(res,out2(lson,left,right));
132     if(right>mid)
133     res=max(res,out2(rson,left,right));
134     if(tr[LL].r&&tr[RR].l&&mid>=left&&mid<right)
135     res=max(res,min(tr[LL].r,mid-left+1)+min(tr[RR].l,right-mid));
136     return res;
137 }
138 int main(){
139     int t;
140     scanf("%d",&t);
141     while(t--)
142     {
143         int n,m;
144         scanf("%d%d",&n,&m);
145         for(int i=1;i<=n;i++)
146             scanf("%d",&a[i]);
147         built(1,n,1);
148         for(int i=1;i<=m;i++)
149         {
150             
151             int x,y,z;
152             scanf("%d%d%d",&x,&y,&z);
153             y++;
154             z++;
155             if(x==0)
156             update(1,n,1,y,z,0);
157             else
158             if(x==1)
159             update(1,n,1,y,z,1);
160             else
161             if(x==2)
162             change(1,n,1,y,z);
163             if(x==3)
164             printf("%d\n",out1(1,n,1,y,z));
165             else
166                if(x==4)
167             printf("%d\n",out2(1,n,1,y,z));
168         }
169     }
170     return 0;
171 }

 

posted @ 2016-12-14 19:36  啊啊啊啊啊啊啊啊啊阿  阅读(323)  评论(0编辑  收藏  举报