【题目描述】:
如题,已知一个数列,你需要进行下面两种操作:
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的结果。
【样例输入】:
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
【样例输出】:
11
8
20
【时间限制、数据范围及描述】:
时间:1s 空间:128M
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据保证在int64/long long数据范围内)
感觉通过加和乘那一题,我的线段树水平有了质的提升,还是那个原则,打延迟标记的时候当前节点也要更新,并且,只要需要访问子节点,就一定要标记下传,无论是查询还是更新!!!
1 #include "bits/stdc++.h" 2 #define mem(a,b) memset(a,b,sizeof(a)) 3 #define lson rt<<1,l,m 4 #define rson rt<<1|1,m+1,r 5 using namespace std; 6 typedef long long LL; 7 const int MAX=100005; 8 int n,m; 9 LL sum[MAX*4],la[MAX*4]; 10 void PushUp(int rt){ 11 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 12 } 13 void PushDown(int rt,int l,int r){ 14 int m=(l+r)>>1; 15 if (la[rt]!=0){ 16 la[rt<<1]+=la[rt];la[rt<<1|1]+=la[rt]; 17 sum[rt<<1]+=la[rt]*(m-l+1);sum[rt<<1|1]+=la[rt]*(r-m); 18 la[rt]=0; 19 } 20 } 21 void build(int rt,int l,int r){ 22 if (l==r){ 23 scanf("%lld",&sum[rt]); 24 la[rt]=0; 25 return; 26 }la[rt]=0; 27 int m=(l+r)>>1; 28 build(lson); 29 build(rson); 30 PushUp(rt); 31 } 32 void update(int rt,int l,int r,LL x,LL y,LL z){ 33 if (x<=l && r<=y){ 34 la[rt]+=z; 35 sum[rt]+=(r-l+1)*z; 36 return; 37 } 38 int m=(l+r)>>1; 39 PushDown(rt,l,r); 40 if (x<=m) 41 update(lson,x,y,z); 42 if (y>m) 43 update(rson,x,y,z); 44 PushUp(rt); 45 } 46 LL search(int rt,int l,int r,int x,int y){ 47 if (x<=l && r<=y) return sum[rt]; 48 LL an=0; 49 int m=(l+r)>>1; 50 PushDown(rt,l,r); 51 if (x<=m) 52 an+=search(lson,x,y); 53 if (y>m) 54 an+=search(rson,x,y); 55 return an; 56 } 57 int main(){ 58 freopen ("segtree.in","r",stdin); 59 freopen ("segtree.out","w",stdout); 60 int i,j; 61 LL x,y,z,w; 62 scanf("%d%d",&n,&m); 63 build(1,1,n); 64 for (i=1;i<=m;i++){ 65 scanf("%lld",&w); 66 if (w==1){ 67 scanf("%lld%lld%lld",&x,&y,&z); 68 update(1,1,n,x,y,z); 69 } 70 if (w==2){ 71 scanf("%lld%lld",&x,&y); 72 printf("%lld\n",search(1,1,n,x,y)); 73 } 74 } 75 return 0; 76 }
时间: 2025-01-05 03:58:34