HDU 3397 线段树区间合并,懒惰思想

Sequence operation

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4910    Accepted Submission(s): 1432


Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
 

 

Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
 

 

Output
For each output operation , output the result.
 

 

Sample Input
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
 

 

Sample Output
5 2 6 5
题意比较简单,给定一个01串,根据题目要求执行更改,查询操作。操作类型比较多,比较复杂,硬着头皮写下来,210行,不容易呀。
代码:
  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 #include<string>
  6 #include<vector>
  7 #include<iterator>
  8 #include<map>
  9 #include<stack>
 10 #include<queue>
 11 #include<math.h>
 12 #include<stdlib.h>
 13 using namespace std;
 14 const int maxn=111111;
 15 #define L(x) 2*x
 16 #define R(x) 2*x+1
 17 struct node
 18 {
 19        int l,r;
 20        int lsum0,rsum0,vsum0;
 21        int lsum1,rsum1,vsum1;
 22        int sum0,sum1;
 23        int mark;
 24        int mid(){return (l+r)>>1;}
 25        int len(){return r-l+1;}
 26        void chang0()
 27        {
 28               sum0=len();
 29               sum1=0;
 30               lsum0=rsum0=vsum0=len();
 31               lsum1=rsum1=vsum1=0;
 32        }
 33        void change1()
 34        {
 35               sum0=0;
 36               sum1=len();
 37               lsum0=rsum0=vsum0=0;
 38               lsum1=rsum1=vsum1=len();
 39        }
 40        void fan()
 41        {
 42               swap(sum0,sum1);
 43               swap(lsum0,lsum1);
 44               swap(rsum0,rsum1);
 45               swap(vsum0,vsum1);
 46        }
 47 }tree[8*maxn];
 48 void pushdown(int p)
 49 {
 50        if(tree[p].mark==-1)return;
 51        if(tree[p].mark==0)
 52        {
 53               tree[L(p)].mark=tree[p].mark;
 54               tree[R(p)].mark=tree[p].mark;
 55               tree[L(p)].chang0();
 56               tree[R(p)].chang0();
 57        }
 58        else if(tree[p].mark==1)
 59        {
 60              tree[L(p)].mark=tree[p].mark;
 61              tree[R(p)].mark=tree[p].mark;
 62              tree[L(p)].change1();
 63              tree[R(p)].change1();
 64        }
 65        else if(tree[p].mark==2)
 66        {
 67               //tree[p].fan();
 68               tree[L(p)].fan();
 69               tree[R(p)].fan();
 70               if(tree[L(p)].mark==-1)tree[L(p)].mark=2;
 71               else if(tree[L(p)].mark==0||tree[L(p)].mark==1)tree[L(p)].mark^=1;
 72               else tree[L(p)].mark=-1;
 73               if(tree[R(p)].mark==-1)tree[R(p)].mark=2;
 74               else if(tree[R(p)].mark==0||tree[R(p)].mark==1)tree[R(p)].mark^=1;
 75               else tree[R(p)].mark=-1;
 76        }
 77        tree[p].mark=-1;
 78 }
 79 void pushup(int p)
 80 {
 81       // pushdown(L(p));pushdown(R(p));
 82        tree[p].sum0=tree[L(p)].sum0+tree[R(p)].sum0;
 83        tree[p].sum1=tree[L(p)].sum1+tree[R(p)].sum1;
 84 
 85        tree[p].lsum0=tree[L(p)].lsum0;
 86        tree[p].rsum0=tree[R(p)].rsum0;
 87        if(tree[L(p)].lsum0==tree[L(p)].len())tree[p].lsum0+=tree[R(p)].lsum0;
 88        if(tree[R(p)].rsum0==tree[R(p)].len())tree[p].rsum0+=tree[L(p)].rsum0;
 89        tree[p].vsum0=max(max(tree[L(p)].vsum0,tree[R(p)].vsum0),tree[L(p)].rsum0+tree[R(p)].lsum0);
 90 
 91        tree[p].lsum1=tree[L(p)].lsum1;
 92        tree[p].rsum1=tree[R(p)].rsum1;
 93        if(tree[L(p)].lsum1==tree[L(p)].len())tree[p].lsum1+=tree[R(p)].lsum1;
 94        if(tree[R(p)].rsum1==tree[R(p)].len())tree[p].rsum1+=tree[L(p)].rsum1;
 95        tree[p].vsum1=max(max(tree[L(p)].vsum1,tree[R(p)].vsum1),tree[L(p)].rsum1+tree[R(p)].lsum1);
 96 }
 97 void build(int p,int l,int r)
 98 {
 99        tree[p].l=l;
100        tree[p].r=r;
101        tree[p].mark=-1;
102        if(l==r)
103        {
104               int c;
105               cin>>c;
106               tree[p].sum1=tree[p].lsum1=tree[p].rsum1=tree[p].vsum1=c;
107               tree[p].sum0=tree[p].lsum0=tree[p].rsum0=tree[p].vsum0=c^1;
108               return;
109        }
110        int m=tree[p].mid();
111        build(L(p),l,m);
112        build(R(p),m+1,r);
113        pushup(p);
114 }
115 void update(int p,int l,int r,int flag)
116 {
117        if(tree[p].l>=l&&tree[p].r<=r)
118        {
119               if(flag==0)
120               {
121                      tree[p].mark=0;
122                      tree[p].chang0();
123               }
124               else if(flag==1)
125               {
126                      tree[p].mark=1;
127                      tree[p].change1();
128               }
129               else if(flag==2)
130               {
131                      if(tree[p].mark==-1)
132                      {
133                             tree[p].mark=2;
134                             tree[p].fan();
135                      }
136                      else if(tree[p].mark==2)
137                      {
138                             tree[p].fan();
139                             tree[p].mark=-1;
140                      }
141                      else if(tree[p].mark==0)
142                      {
143                             tree[p].mark=1;
144                             tree[p].change1();
145                      }
146                      else if(tree[p].mark==1)
147                      {
148                             tree[p].mark=0;
149                             tree[p].chang0();
150                      }
151               }
152               return;
153        }
154        pushdown(p);
155        int m=tree[p].mid();
156        if(l<=m)update(L(p),l,r,flag);
157        if(r>m)update(R(p),l,r,flag);
158        pushup(p);
159 }
160 int query_one(int p,int l,int r)
161 {
162        if(tree[p].l>=l&&tree[p].r<=r)return tree[p].sum1;
163        pushdown(p);
164        int  ans=0;
165        int m=tree[p].mid();
166        if(l<=m)ans+=query_one(L(p),l,r);
167        if(r>m)ans+=query_one(R(p),l,r);
168        return ans;
169 }
170 int query(int p,int l,int r)
171 {
172        if(tree[p].l>=l&&tree[p].r<=r)return tree[p].vsum1;
173        pushdown(p);
174        int ans;
175        int m=tree[p].mid();
176        if(r<=m)return query(L(p),l,r);
177        else if(l>m)return query(R(p),l,r);
178 
179        else
180        {
181               int t1=query(L(p),l,r);
182               int t2=query(R(p),l,r);
183               ans=max(t1,t2);
184               t1=min(tree[L(p)].rsum1,m-l+1);
185               t2=min(tree[R(p)].lsum1,r-m);
186               ans=max(ans,t1+t2);
187        }
188        return ans;
189 }
190 int main()
191 {
192        int i,j,k,m,n,T;
193        //freopen("data.in","r",stdin);
194        scanf("%d",&T);
195        while(T--)
196        {
197               scanf("%d%d",&n,&m);
198               build(1,1,n);
199               int  op,a,b;
200               while(m--)
201               {
202                      scanf("%d%d%d",&op,&a,&b);
203                      a++;b++;
204                      if(op<3)update(1,a,b,op);
205                      else if(op==3)printf("%d\n",query_one(1,a,b));
206                      else if(op==4)printf("%d\n",query(1,a,b));
207               }
208        }
209        return 0;
210 }

 

 
posted @ 2013-10-03 14:12  线性无关  阅读(112)  评论(0)    收藏  举报