HDU-4578 Transformation (multiple section operation of the segment tree)

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. 

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.

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 }

 

 
 
 
 
 
 
 
 
 
 
 
 
 

Guess you like

Origin www.cnblogs.com/jiamian/p/11421697.html
Recommended