hdu 3397 线段树综合

思路:

       线段树结构更新维护,结构内部包括  1的最大左连续、最大右连续、最大连续长度,0的最大左连续、最大右连续、最大连续长度,1的个数、覆盖值、取反,一共9个值,其中的取反操作要特别注意,其余的看代码吧。。

       如果代码看不懂的话,建议先做一下区间最大连续和、还有poj 3225.

View Code
  1 #include<iostream>
  2 #include<stdio.h>
  3 using namespace std;
  4 const int N = 100003;
  5 struct node
  6 {
  7        int lo,ro,mo;
  8        int lz,rz,mz;
  9        int oc,cover,re; 
 10        int len;
 11 }tree[N<<2];
 12 int Max(int a,int b)
 13 {
 14     return a>b?a:b;
 15 }
 16 void Get_Re(int t)
 17 {
 18      if(tree[t].cover!=-1)tree[t].cover^=1;
 19      else tree[t].re^=1;
 20 }
 21 void PushDown(int t,int m)
 22 {
 23      if(tree[t].cover!=-1)
 24      {
 25         int t1=t<<1;
 26         int t2=t1|1;
 27         int ll=m-(m>>1),rr=(m>>1);
 28         tree[t1].cover=tree[t2].cover=tree[t].cover;
 29         tree[t1].re=tree[t2].re=0;
 30         tree[t1].lo=tree[t1].ro=tree[t1].mo=(tree[t].cover?ll:0);
 31         tree[t1].lz=tree[t1].rz=tree[t1].mz=(tree[t].cover?0:ll);
 32         tree[t2].lo=tree[t2].ro=tree[t2].mo=(tree[t].cover?rr:0);
 33         tree[t2].lz=tree[t2].rz=tree[t2].mz=(tree[t].cover?0:rr);
 34         tree[t1].oc=(tree[t].cover?ll:0);
 35         tree[t2].oc=(tree[t].cover?rr:0);
 36         tree[t].cover=-1;
 37      }
 38      if(tree[t].re)
 39      {
 40         int t1=t<<1;
 41         int t2=t1|1;
 42         int ll=m-(m>>1),rr=(m>>1);
 43         Get_Re(t1);Get_Re(t2);
 44         swap(tree[t1].lo,tree[t1].lz);swap(tree[t1].ro,tree[t1].rz);swap(tree[t1].mo,tree[t1].mz);
 45         tree[t1].oc=ll-tree[t1].oc;
 46         swap(tree[t2].lo,tree[t2].lz);swap(tree[t2].ro,tree[t2].rz);swap(tree[t2].mo,tree[t2].mz);  
 47         tree[t2].oc=rr-tree[t2].oc;
 48         tree[t].re=0;
 49      }
 50 }
 51 void PushUp(int t,int m)
 52 {
 53      int t1=t<<1;
 54      int t2=t1|1;
 55      int ll=m-(m>>1),rr=m>>1;
 56      tree[t].oc=tree[t1].oc+tree[t2].oc;
 57      
 58      tree[t].lo=tree[t1].lo;
 59      if(tree[t].lo==ll)tree[t].lo+=tree[t2].lo;
 60      tree[t].ro=tree[t2].ro;
 61      if(tree[t].ro==rr)tree[t].ro+=tree[t1].ro;
 62      tree[t].mo=Max(tree[t1].ro+tree[t2].lo,Max(tree[t1].mo,tree[t2].mo));
 63      
 64      tree[t].lz=tree[t1].lz;
 65      if(tree[t].lz==ll)tree[t].lz+=tree[t2].lz;
 66      tree[t].rz=tree[t2].rz;
 67      if(tree[t].rz==rr)tree[t].rz+=tree[t1].rz;
 68      tree[t].mz=Max(tree[t1].rz+tree[t2].lz,Max(tree[t1].mz,tree[t2].mz));
 69 }
 70 void build(int t,int l,int r)
 71 {
 72      tree[t].re=0;
 73      tree[t].cover=-1;
 74      tree[t].len=(r-l+1);
 75      if(l==r)
 76      {
 77         scanf("%d",&tree[t].oc);
 78         tree[t].lo=tree[t].ro=tree[t].mo=(tree[t].oc);
 79         tree[t].lz=tree[t].rz=tree[t].mz=(tree[t].oc?0:1);
 80         return ;
 81      }
 82      int m=(l+r)>>1;
 83      build(t<<1,l,m);
 84      build(t<<1|1,m+1,r);
 85      PushUp(t,r-l+1);
 86 }
 87 void update(int t,int l,int r,int L,int R,int o,int val)
 88 {
 89      if(L<=l&&r<=R)
 90      {
 91         if(o==2)
 92         {
 93            Get_Re(t);
 94            tree[t].oc=(r-l+1)-tree[t].oc;
 95            swap(tree[t].lo,tree[t].lz);swap(tree[t].ro,tree[t].rz);swap(tree[t].mo,tree[t].mz);
 96         }
 97         else
 98         {
 99            tree[t].lo=tree[t].ro=tree[t].mo=(val?r-l+1:0);
100            tree[t].lz=tree[t].rz=tree[t].mz=(val?0:r-l+1);
101            tree[t].oc=(val?(r-l+1):0);
102            tree[t].cover=val;
103            tree[t].re=0;
104         }   
105         return ;           
106      }
107      PushDown(t,r-l+1);
108      int m=(l+r)>>1;
109      if(L<=m)update(t<<1,l,m,L,R,o,val);
110      if(R>m)update(t<<1|1,m+1,r,L,R,o,val);
111      PushUp(t,r-l+1);
112 }
113 int query1(int t,int l,int r,int L,int R)
114 {
115      if(L<=l&&r<=R)return tree[t].oc;
116      if(l==r)return 0;
117      PushDown(t,r-l+1);
118      int m=(l+r)>>1;
119      int answer=0;
120      if(L<=m)answer+=query1(t<<1,l,m,L,R);
121      if(R>m)answer+=query1(t<<1|1,m+1,r,L,R);
122      return answer;
123 }
124 node query2(int t,int l,int r,int L,int R)
125 {
126      node temp={0};
127      if(L<=l&&r<=R)return tree[t];
128      if(l==r)return tree[t];
129      PushDown(t,r-l+1);
130      int m=(l+r)>>1;
131      node t1,t2;
132      int flag1=0,flag2=0;
133      if(L<=m){t1=query2(t<<1,l,m,L,R);flag1=1;}
134      if(R>m){t2=query2(t<<1|1,m+1,r,L,R);flag2=1;}
135      if(flag1&&flag2)
136      {
137         temp.len=t1.len+t2.len;
138         temp.lo=t1.lo;
139         if(temp.lo==t1.len)temp.lo+=t2.lo;
140         temp.ro=t2.ro;
141         if(temp.ro==t2.len)temp.ro+=t1.ro;
142         temp.mo=Max(t1.ro+t2.lo,Max(t1.mo,t2.mo));
143         return temp;
144      }
145      else
146        if(flag1)return t1;
147        else return t2;
148 }
149 int main()
150 {
151    // freopen("in.txt","r",stdin);
152   //  freopen("out2.txt","w",stdout);
153     int Case,n,m,o,a,b;
154     scanf("%d",&Case);
155     while(Case--)
156     {
157         scanf("%d%d",&n,&m);
158         n--;
159         build(1,0,n);
160         while (m--)
161         {
162              scanf("%d%d%d",&o,&a,&b);
163              if(o<=2)
164                 update(1,0,n,a,b,o,o);
165              else
166              {
167                 if(o==3)printf("%d\n",query1(1,0,n,a,b));
168                 else 
169                 {
170                    node temp=query2(1,0,n,a,b);
171                    printf("%d\n",temp.mo);
172                 }
173              }
174         }
175     }
176     return 0;    
177 }

 

posted @ 2012-10-24 18:58  诺小J  阅读(154)  评论(0编辑  收藏  举报