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
2013ACM-ICPC杭州赛区全国邀请赛
很裸的线段树的题目。
但是做起来比较麻烦。
我用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 }