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]
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.
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 }

浙公网安备 33010602011771号