HDU 4578 Transformation (線段樹)


Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 49    Accepted Submission(s): 16


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
 

 

 

很裸的線段樹的題目。

 

但是做起來比較麻煩。

 

我用sum1,sum2,sum3分別代表和、平方和、立方和。

 

懶惰標記使用三個變量:

lazy1:是加的數

lazy2:是乘的倍數

lazy3:是賦值為一個常數,為0表示沒有。

 

更新操作需要注意很多細節。

 

 

  1 /* **********************************************
  2 Author      : kuangbin
  3 Created Time: 2013/8/10 13:24:03
  4 File Name   : F:\2013ACM練習\比賽練習\2013杭州邀請賽重現\1003.cpp
  5 *********************************************** */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 using namespace std;
 19 const int MOD = 10007;
 20 const int MAXN = 100010;
 21 struct Node
 22 {
 23     int l,r;
 24     int sum1,sum2,sum3;
 25     int lazy1,lazy2,lazy3;
 26 }segTree[MAXN*3];
 27 void build(int i,int l,int r)
 28 {
 29     segTree[i].l = l;
 30     segTree[i].r = r;
 31     segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = 0;
 32     segTree[i].lazy1 = segTree[i].lazy3 = 0;
 33     segTree[i].lazy2 = 1;
 34     int mid = (l+r)/2;
 35     if(l == r)return;
 36     build(i<<1,l,mid);
 37     build((i<<1)|1,mid+1,r);
 38 }
 39 void push_up(int i)
 40 {
 41     if(segTree[i].l == segTree[i].r)
 42         return;
 43     segTree[i].sum1 = (segTree[i<<1].sum1 + segTree[(i<<1)|1].sum1)%MOD;
 44     segTree[i].sum2 = (segTree[i<<1].sum2 + segTree[(i<<1)|1].sum2)%MOD;
 45     segTree[i].sum3 = (segTree[i<<1].sum3 + segTree[(i<<1)|1].sum3)%MOD;
 46 
 47 }
 48 
 49 void push_down(int i)
 50 {
 51     if(segTree[i].l == segTree[i].r) return;
 52     if(segTree[i].lazy3 != 0)
 53     {
 54         segTree[i<<1].lazy3 = segTree[(i<<1)|1].lazy3 = segTree[i].lazy3;
 55         segTree[i<<1].lazy1 = segTree[(i<<1)|1].lazy1 = 0;
 56         segTree[i<<1].lazy2 = segTree[(i<<1)|1].lazy2 = 1;
 57         segTree[i<<1].sum1 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD;
 58         segTree[i<<1].sum2 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
 59         segTree[i<<1].sum3 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
 60         segTree[(i<<1)|1].sum1 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD;
 61         segTree[(i<<1)|1].sum2 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
 62         segTree[(i<<1)|1].sum3 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
 63         segTree[i].lazy3 = 0;
 64     }
 65     if(segTree[i].lazy1 != 0 || segTree[i].lazy2 != 1)
 66     {
 67         segTree[i<<1].lazy1 = ( segTree[i].lazy2*segTree[i<<1].lazy1%MOD + segTree[i].lazy1 )%MOD;
 68         segTree[i<<1].lazy2 = segTree[i<<1].lazy2*segTree[i].lazy2%MOD;
 69         int sum1,sum2,sum3;
 70         sum1 = (segTree[i<<1].sum1*segTree[i].lazy2%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD)%MOD;
 71         sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<1].sum1%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
 72         sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<1].sum3 % MOD;
 73         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum2) % MOD;
 74         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum1) % MOD;
 75         sum3 = (sum3 + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
 76         segTree[i<<1].sum1 = sum1;
 77         segTree[i<<1].sum2 = sum2;
 78         segTree[i<<1].sum3 = sum3;
 79         segTree[(i<<1)|1].lazy1 = ( segTree[i].lazy2*segTree[(i<<1)|1].lazy1%MOD + segTree[i].lazy1 )%MOD;
 80         segTree[(i<<1)|1].lazy2 = segTree[(i<<1)|1].lazy2 * segTree[i].lazy2 % MOD;
 81         sum1 = (segTree[(i<<1)|1].sum1*segTree[i].lazy2%MOD + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD)%MOD;
 82         sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[(i<<1)|1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[(i<<1)|1].sum1%MOD + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
 83         sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[(i<<1)|1].sum3 % MOD;
 84         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<1)|1].sum2) % MOD;
 85         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<1)|1].sum1) % MOD;
 86         sum3 = (sum3 + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
 87         segTree[(i<<1)|1].sum1 = sum1;
 88         segTree[(i<<1)|1].sum2 = sum2;
 89         segTree[(i<<1)|1].sum3 = sum3;
 90         segTree[i].lazy1 = 0;
 91         segTree[i].lazy2 = 1;
 92 
 93     }
 94 }
 95 void update(int i,int l,int r,int type,int c)
 96 {
 97     if(segTree[i].l == l && segTree[i].r == r)
 98     {
 99         c %= MOD;
100         if(type == 1)
101         {
102             segTree[i].lazy1 += c;
103             segTree[i].lazy1 %= MOD;
104             segTree[i].sum3 = (segTree[i].sum3 + 3*segTree[i].sum2%MOD*c%MOD + 3*segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD*c%MOD)%MOD;
105             segTree[i].sum2 = (segTree[i].sum2 + 2*segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD)%MOD;
106             segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + 1)*c%MOD)%MOD;
107         }
108         else if(type == 2)
109         {
110             segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
111             segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
112             segTree[i].sum1 = segTree[i].sum1*c%MOD;
113             segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
114             segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
115         }
116         else
117         {
118             segTree[i].lazy1 = 0;
119             segTree[i].lazy2 = 1;
120             segTree[i].lazy3 = c%MOD;
121             segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + 1)%MOD;
122             segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD;
123             segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD*c%MOD;
124         }
125         return;
126     }
127     push_down(i);
128     int mid = (segTree[i].l + segTree[i].r)/2;
129     if(r <= mid)update(i<<1,l,r,type,c);
130     else if(l > mid)update((i<<1)|1,l,r,type,c);
131     else
132     {
133         update(i<<1,l,mid,type,c);
134         update((i<<1)|1,mid+1,r,type,c);
135     }
136     push_up(i);
137 }
138 int query(int i,int l,int r,int p)
139 {
140     if(segTree[i].l == l && segTree[i].r == r)
141     {
142         if(p == 1)return segTree[i].sum1;
143         else if(p== 2)return segTree[i].sum2;
144         else return segTree[i].sum3;
145     }
146     push_down(i);
147     int mid = (segTree[i].l + segTree[i].r )/2;
148     if(r <= mid)return query(i<<1,l,r,p);
149     else if(l > mid)return query((i<<1)|1,l,r,p);
150     else return (query(i<<1,l,mid,p)+query((i<<1)|1,mid+1,r,p))%MOD;
151 }
152 
153 int main()
154 {
155     //freopen("in.txt","r",stdin);
156     //freopen("out.txt","w",stdout);
157     int n,m;
158     while(scanf("%d%d",&n,&m) == 2)
159     {
160         if(n == 0 && m == 0)break;
161         build(1,1,n);
162         int type,x,y,c;
163         while(m--)
164         {
165             scanf("%d%d%d%d",&type,&x,&y,&c);
166             if(type == 4)printf("%d\n",query(1,x,y,c));
167             else update(1,x,y,type,c);
168         }
169     }
170     return 0;
171 }

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM