洛谷P3372 【模板】线段树 1(线段树+区间加+区间求和)
题目描述
如题,已知一个数列,你需要进行下面两种操作:
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的结果。
输入输出样例
输入 #1
5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4
输出 #1
11 8 20
说明/提示
时空限制:1000ms,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 using namespace std; 3 typedef long long ll; 4 5 const ll MAXN=100000+5; 6 ll st[MAXN<<2],lazy[MAXN<<2];///lazy懒标记数组 7 ll n,m; 8 9 void pushup(ll rt) 10 { 11 st[rt]=st[rt<<1]+st[rt<<1|1]; 12 } 13 void pushdown(ll l,ll r,ll rt) 14 { 15 if(lazy[rt]==0)return; 16 lazy[rt<<1]+=lazy[rt]; 17 lazy[rt<<1|1]+=lazy[rt]; 18 ll mid=(l+r)>>1; 19 st[rt<<1]+=lazy[rt]*(mid-l+1); 20 st[rt<<1|1]+=lazy[rt]*(r-mid); 21 lazy[rt]=0; 22 } 23 void build(ll l,ll r,ll rt) 24 { 25 lazy[rt]=0; 26 if(l==r) 27 { 28 st[rt]=0; 29 return; 30 } 31 ll mid=(l+r)>>1; 32 pushdown(l,r,rt); 33 build(l,mid,rt<<1); 34 build(mid+1,r,rt<<1|1); 35 pushup(rt); 36 } 37 void update(ll L,ll R,ll val,ll l,ll r,ll rt) 38 { 39 if(L<=l&&r<=R) 40 { 41 lazy[rt]+=val; 42 st[rt]+=(r-l+1)*val; 43 return; 44 } 45 pushdown(l,r,rt); 46 ll mid=(l+r)>>1; 47 if(L<=mid)update(L,R,val,l,mid,rt<<1); 48 if(R>mid)update(L,R,val,mid+1,r,rt<<1|1); 49 pushup(rt); 50 } 51 ll query(ll L,ll R,ll l,ll r,ll rt) 52 { 53 if(L<=l&&r<=R)return st[rt]; 54 pushdown(l,r,rt); 55 ll mid=(l+r)>>1,res=0; 56 if(L<=mid)res+=query(L,R,l,mid,rt<<1); 57 if(R>mid)res+=query(L,R,mid+1,r,rt<<1|1); 58 pushup(rt); 59 return res; 60 } 61 int main() 62 { 63 ll x,y,v,op; 64 scanf("%lld%lld",&n,&m); 65 build(1,n,1); 66 for(ll i=1; i<=n; i++) 67 { 68 scanf("%lld",&x); 69 update(i,i,x,1,n,1); 70 } 71 for(ll i=1; i<=m; i++) 72 { 73 scanf("%lld",&op); 74 if(op==1) 75 { 76 scanf("%lld%lld%lld",&x,&y,&v); 77 update(x,y,v,1,n,1); 78 } 79 else if(op==2) 80 { 81 scanf("%lld%lld",&x,&y); 82 printf("%lld\n",query(x,y,1,n,1)); 83 } 84 } 85 }