Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 49 Accepted Submission(s): 16
There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations.
Operation 1: Add c to each number between ax and ay inclusive. In other words, do transformation ak<---ak+c, k = x,x+1,…,y.
Operation 2: Multiply c to each number between ax and ay inclusive. In other words, do transformation ak<---ak×c, k = x,x+1,…,y.
Operation 3: Change the numbers between ax and ay to c, inclusive. In other words, do transformation ak<---c, k = x,x+1,…,y.
Operation 4: Get the sum of p power among the numbers between ax and ay inclusive. In other words, get the result of axp+ax+1p+…+ay p.
Yuanfang has no idea of how to do it. So he wants to ask you to help him.
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.
很裸的线段树的题目。
但是做起来比较麻烦。
我用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 }