题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数加上x
2.求出某区间每一个数的和
输入输出格式
输入格式:
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k
操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和
输出格式:
输出包含若干行整数,即为所有操作2的结果。
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^,保证在int64/long long数据范围内)
AC代码:
1 #include<iostream> 2 using namespace std; 3 long long n,m,a[10000005],p,x,y,pp; 4 struct kkk{ 5 int l,r;//l、r分别代表此节点所含信息区间左端和右端 6 long long add,tql;//add是lazy标记,tql代表此节点所含区间和。 7 }t[10000005]; 8 void build(int q,int w,int e) { 9 t[q].l = w;t[q].r = e; 10 if(w == e) { //如果只维护一个节点的信息,说明为叶节点 11 t[q].tql = a[w]; 12 return ; 13 } 14 int mid = w + e >> 1; 15 build(2*q, w, mid); //建左子树 16 build(2*q+1, mid+1, e); //建右子树 17 t[q].tql = t[q*2].tql + t[q*2+1].tql; //一个节点的信息由它的左右儿子得来 18 } 19 void spr(int o) {//运用lazy标记进行区间修改 20 if(t[o].add) { 21 t[2*o].tql += t[o].add * (t[2*o].r - t[2*o].l + 1); 22 t[o*2+1].tql += t[o].add * (t[o*2+1].r - t[o*2+1].l + 1); 23 t[o*2].add += t[o].add; 24 t[o*2+1].add += t[o].add; 25 t[o].add = 0; 26 } 27 } 28 void pl(int o,int l,int r,int k) { 29 if(l <= t[o].l && r >= t[o].r) {//如果已知区间被所求全部包含,那么直接计算即可 30 t[o].tql += (long long) k * (t[o].r - t[o].l + 1); 31 t[o].add += k; 32 return ; 33 } 34 spr(o); 35 int mid = t[o].l + t[o].r >> 1; 36 if(x <= mid) pl(o*2,x,y,k);//如果x<=mid,说明左半区间包含要求区间 37 if(y > mid) pl(o*2+1,x,y,k); //如果x>=mid ,说明右半区间包含要求区间 38 t[o].tql = t[o*2].tql + t[o*2+1].tql; 39 } 40 long long pr(int p,int x,int y){ 41 if(x <= t[p].l && y >= t[p].r) return t[p].tql; 42 spr(p); 43 int mid = t[p].l + t[p].r >> 1; 44 long long ans = 0; 45 if(x<=mid) ans += pr(p*2,x,y);//如果x<=mid,说明左半子树包含答案 46 if(y>mid) ans += pr(p*2+1,x,y);//如果x>mid,说明右半子树包含答案 47 return ans; 48 } 49 int main(){ 50 cin >> n >> m; 51 for(int i = 1;i <= n; i++) cin >> a[i]; 52 build(1,1,n);//建树 53 for(int i = 1;i <= m; i++) { 54 cin >> p; 55 if(p == 1) { 56 cin >> x >> y >> pp; 57 pl(1,x, y, pp); 58 } 59 else { 60 cin >> x >> y; 61 cout << pr(1,x,y) << endl; 62 } 63 } 64 65 return 0; 66 }