http://acm.hdu.edu.cn/showproblem.php?pid=4578
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Problem Description
Yuanfang is puzzled with the question below:
There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y.
Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
There are n integers, a 1, a 2, …, a n. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between a x and a y inclusive. In other words, do transformation a k<---a k+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between a x and a y inclusive. In other words, do transformation a k<---a k×c, k = x,x+1,…,y.
Operation 3: Change the numbers between a x and a y to c, inclusive. In other words, do transformation a k<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between a x and a y inclusive. In other words, get the result of a x p+a x+1 p+…+a y p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
Input
There are no more than 10 test cases.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.
Each the following m lines contains an operation. Operation 1 to 3 is in this format: "1 x y c" or "2 x y c" or "3 x y c". Operation 4 is in this format: "4 x y p". (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)
The input ends with 0 0.
Output
For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.
Sample Input
5 5 3 3 5 7 1 2 4 4 4 1 5 2 2 2 5 8 4 3 5 3 0 0
Sample Output
307 7489
Source
1 /* 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 const int maxn = 100010 ; 7 #define left v<<1 8 #define right v<<1|1 9 #define mod 10007 10 struct node 11 { 12 int l ,r , value ; 13 int eq , add , mul ; 14 }tree[maxn<<2]; 15 void build(int l , int r , int v) 16 { 17 tree[v].l = l ; 18 tree[v].r = r ; 19 tree[v].add = 0 ; tree[v].mul = 1 ;tree[v].eq = -1 ; 20 if(l == r) 21 {tree[v].eq = 0 ; return ;} 22 int mid = (l + r) >> 1 ; 23 build(l , mid , left) ; 24 build(mid + 1 , r , right) ; 25 } 26 void push_down(int v) 27 { 28 if(tree[v].l == tree[v].r)return ; 29 if(tree[v].eq != -1) 30 { 31 tree[left].eq = tree[right].eq = tree[v].eq ; 32 tree[left].add = tree[right].add = 0 ; 33 tree[left].mul = tree[right].mul = 1; 34 tree[v].eq = -1; 35 return ; 36 } 37 if(tree[v].mul != 1) 38 { 39 if(tree[left].eq != -1) 40 tree[left].eq = (tree[left].eq*tree[v].mul)%mod ; 41 else 42 { 43 push_down(left) ; 44 tree[left].mul = (tree[left].mul*tree[v].mul)%mod ; 45 } 46 if(tree[right].eq != -1) 47 tree[right].eq = (tree[right].eq*tree[v].mul)%mod ; 48 else 49 { 50 push_down(right) ; 51 tree[right].mul = (tree[right].mul*tree[v].mul)%mod ; 52 } 53 tree[v].mul = 1; 54 } 55 if(tree[v].add) 56 { 57 if(tree[left].eq != -1) 58 tree[left].eq = (tree[left].eq + tree[v].add)%mod ; 59 else 60 { 61 push_down(left) ; 62 tree[left].add = (tree[left].add + tree[v].add)%mod ; 63 } 64 if(tree[right].eq != -1) 65 tree[right].eq = (tree[right].eq + tree[v].add)%mod ; 66 else 67 { 68 push_down(right) ; 69 tree[right].add = (tree[right].add + tree[v].add)%mod ; 70 } 71 tree[v].add = 0 ; 72 } 73 } 74 void update(int l , int r , int v , int op , int c) 75 { 76 if(l <= tree[v].l && tree[v].r <= r) 77 { 78 if(op == 3) 79 { 80 tree[v].add = 0 ;tree[v].mul = 1; 81 tree[v].eq = c ; 82 return ; 83 } 84 if(tree[v].eq != -1) 85 { 86 if(op == 1)tree[v].eq = (tree[v].eq + c)%mod ; 87 else tree[v].eq = (tree[v].eq*c)%mod ; 88 } 89 else 90 { 91 push_down(v) ; 92 if(op == 1)tree[v].add = (tree[v].add + c)%mod ; 93 else tree[v].mul = (tree[v].mul*c)%mod ; 94 } 95 return ; 96 } 97 push_down(v) ; 98 int mid = (tree[v].l + tree[v].r) >> 1 ; 99 if(l <= mid)update(l , r ,left , op , c) ; 100 if(r > mid)update(l , r , right , op , c) ; 101 } 102 int query(int l , int r , int v , int q) 103 { 104 if(tree[v].l >= l && tree[v].r <= r && tree[v].eq != -1) 105 { 106 int ans = 1; 107 for(int i = 1;i <= q;i++) 108 ans = (ans * tree[v].eq)%mod ; 109 return (ans*((tree[v].r - tree[v].l + 1)%mod))%mod ; 110 } 111 push_down(v) ; 112 int mid = (tree[v].l + tree[v].r) >> 1 ; 113 if(l > mid)return query(l , r , right, q) ; 114 else if(r <= mid)return query(l , r ,left ,q) ; 115 else return (query(l , mid , left , q) + query(mid + 1 , r , right , q))%mod ; 116 } 132 } 133 return 0 ; 134 } 135 */ 136 137 138 #include <stdio.h> 139 #include <string.h> 140 #include <iostream> 141 #include <string> 142 #include <math.h> 143 #include <algorithm> 144 #include <vector> 145 #include <queue> 146 #include <set> 147 #include <stack> 148 #include <map> 149 #include <math.h> 150 const int INF=0x3f3f3f3f; 151 typedef long long LL; 152 const int mod=1e4+7; 153 //const int mod=1e9+7; 154 //const double PI=acos(-1); 155 const int maxn=1e5+10; 156 using namespace std; 157 //ios::sync_with_stdio(false); 158 // cin.tie(NULL); 159 160 struct SegTree_node 161 { 162 int l; 163 int r; 164 int num; 165 int add; 166 int mul; 167 int eq; 168 }SegTree[maxn<<2]; 169 170 int n,m; 171 172 void Build(int l,int r,int rt)// 173 { 174 SegTree[rt].l=l; 175 SegTree[rt].r=r; 176 SegTree[rt].add=0; 177 SegTree[rt].mul=1; 178 SegTree[rt].eq=-1; 179 if(l==r) 180 { 181 SegTree[rt].eq=0; 182 return ; 183 } 184 int mid=(l+r)>>1; 185 Build(l,mid,rt<<1); 186 Build(mid+1,r,rt<<1|1); 187 } 188 189 void PushDown(int rt)// 190 { 191 int l=SegTree[rt].l; 192 int r=SegTree[rt].r; 193 if(l==r) 194 return ; 195 if(SegTree[rt].eq!=-1) 196 { 197 SegTree[rt<<1].eq=SegTree[rt<<1|1].eq=SegTree[rt].eq; 198 SegTree[rt<<1].add=SegTree[rt<<1|1].add=0; 199 SegTree[rt<<1].mul=SegTree[rt<<1|1].mul=1; 200 SegTree[rt].eq=-1; 201 return ; 202 } 203 if(SegTree[rt].mul!=1) 204 { 205 if(SegTree[rt<<1].eq!=-1) 206 SegTree[rt<<1].eq=(SegTree[rt<<1].eq*SegTree[rt].mul)%mod; 207 else 208 { 209 Pushdowns (rt << 1 ); 210 SegTree [rt << 1 ] .mul = (SegTree [rt << 1 ] * .mul SegTree [rt] .mul)% mod; 211 } 212 if (SegTree [rt << 1 | 1 ] .eq! = - 1 ) 213 SegTree [rt << 1 | 1 ] .eq = (SegTree [rt << 1 | 1 ] * .eq SegTree [rt] .mul)% mod; 214 else 215 { 216 pushdowns (rt << 1 | 1 ) 217 SegTree[rt<<1|1].mul=(SegTree[rt<<1|1].mul*SegTree[rt].mul)%mod; 218 } 219 SegTree[rt].mul=1; 220 } 221 if(SegTree[rt].add) 222 { 223 if(SegTree[rt<<1].eq!=-1) 224 SegTree[rt<<1].eq=(SegTree[rt<<1].eq+SegTree[rt].add)%mod; 225 else 226 { 227 PushDown(rt<<1); 228 SegTree[rt<<1].add=(SegTree[rt<<1].add+SegTree[rt].add)%mod; 229 } 230 if(SegTree[rt<<1|1].eq!=-1) 231 SegTree[rt<<1|1].eq=(SegTree[rt<<1|1].eq+SegTree[rt].add)%mod; 232 else 233 { 234 PushDown(rt<<1|1); 235 SegTree[rt<<1|1].add=(SegTree[rt<<1|1].add+SegTree[rt].add)%mod; 236 } 237 SegTree[rt].add=0; 238 } 239 } 240 241 void Update(int L,int R,int C,int op,int rt) 242 { 243 int l=SegTree[rt].l; 244 int r=SegTree[rt].r; 245 if(L<=l&&R>=r) 246 { 247 if(op==3) 248 { 249 SegTree[rt].add=0; 250 SegTree[rt].mul=1; 251 SegTree[rt].eq=C; 252 return ; 253 } 254 if(SegTree[rt].eq!=-1) 255 { 256 if(op==1) 257 SegTree[rt].eq=(SegTree[rt].eq+C)%mod; 258 else if(op==2) 259 SegTree[rt].eq=(SegTree[rt].eq*C)%mod; 260 } 261 else 262 { 263 PushDown(rt); 264 if(op==1) 265 SegTree[rt].add=(SegTree[rt].add+C)%mod; 266 else if(op==2) 267 SegTree[rt].mul=(SegTree[rt].mul*C)%mod; 268 } 269 return ; 270 } 271 PushDown(rt);//向下传递状态 272 int mid=(l+r)>>1; 273 if(L<=mid) 274 Update(L,R,C,op,rt<<1); 275 if(R>mid) 276 Update(L,R,C,op,rt<<1|1); 277 } 278 279 int Query(int L,int R,int P,int rt) 280 { 281 int l=SegTree[rt].l; 282 int r=SegTree[rt].r; 283 if(L<=l&&R>=r) 284 { 285 int ans=1; 286 for(int i=1;i<=P;i++) 287 ans=(ans*SegTree[rt].eq)%mod; 288 return (ans*(r-l+1)) %mod; 289 } 290 PushDown(rt); 291 int mid=(l+r)>>1; 292 if(R<=mid) 293 return Query(L,R,P,rt<<1); 294 else if(L>mid) 295 return Query(L,R,P,rt<<1|1); 296 else 297 return (Query(L,mid,P,rt<<1)+Query(mid+1,R,P,rt<<1|1))%mod; 298 } 299 300 int main() 301 { 302 freopen("sample.txt","r",stdin); 303 while(~scanf("%d %d",&n,&m)&&(n||m)) 304 { 305 for(int i=1;i<=m;i++) 306 { 307 int op,x,y,c; 308 scanf("%d %d %d %d",&op,&x,&y,&c); 309 printf("**********\n"); 310 if(op<=3) 311 Update(x,y,c,op,1); ) 4(on ==ifelse312 313 printf("%d\n",Query(x,y,c,1)%mod); 314 } 315 } 316 return 0; 317 }