洛谷 P3372 【模板】线段树 1
这题是线段树的区间加、区间修改和懒标记,注意开long long
1 #include<bits/stdc++.h> 2 #define ls (x<<1) 3 #define rs (x<<1|1) 4 #define rep(i,a,b) for(int i=a;i<=b;i++) 5 #define pb(a) push_back(a) 6 using namespace std; 7 typedef long long ll; 8 typedef pair<int,int> pii; 9 const int N=1e5+5; 10 int n,m; 11 ll sum[N<<2],tag[N<<1],a[N]; 12 void update(int x) 13 { 14 sum[x]=sum[ls]+sum[rs]; 15 } 16 void down(int l,int r,int x) 17 { 18 int mid=(l+r)>>1; 19 if(tag[x]) 20 { 21 tag[ls]+=tag[x]; 22 tag[rs]+=tag[x]; 23 sum[ls]+=1ll*(mid-l+1)*tag[x]; 24 sum[rs]+=1ll*(r-mid)*tag[x]; 25 tag[x]=0; 26 } 27 } 28 void build(int l,int r,int x) 29 { 30 if(l==r) 31 { 32 sum[x]=a[l]; 33 return; 34 } 35 int mid=(l+r)>>1; 36 build(l,mid,ls); 37 build(mid+1,r,rs); 38 update(x); 39 } 40 void modify(int A,int B,int l,int r,int v,int x) 41 { 42 if(A<=l&&B>=r) 43 { 44 sum[x]+=1ll*(r-l+1)*v; 45 tag[x]+=v; 46 return; 47 } 48 down(l,r,x); 49 int mid=(l+r)>>1; 50 if(A<=mid)modify(A,B,l,mid,v,ls); 51 if(B>mid)modify(A,B,mid+1,r,v,rs); 52 update(x); 53 } 54 ll query(int A,int B,int l,int r,int x) 55 { 56 if(A<=l&&B>=r)return sum[x]; 57 down(l,r,x); 58 ll mid=(l+r)>>1,ret=0; 59 if(A<=mid)ret+=query(A,B,l,mid,ls); 60 if(B>mid)ret+=query(A,B,mid+1,r,rs); 61 return ret; 62 } 63 int main() 64 { 65 /* 66 freopen("P3372_8.in","r",stdin); 67 freopen("answer.txt","w",stdout); 68 */ 69 scanf("%d%d",&n,&m); 70 rep(i,1,n) 71 scanf("%d",&a[i]); 72 build(1,n,1); 73 rep(i,1,m) 74 { 75 int op; 76 scanf("%d",&op); 77 if(op==1) 78 { 79 int l,r,v; 80 scanf("%d%d%d",&l,&r,&v); 81 modify(l,r,1,n,v,1); 82 } 83 else 84 { 85 int l,r; 86 scanf("%d%d",&l,&r); 87 printf("%lld\n",query(l,r,1,n,1)); 88 } 89 } 90 return 0; 91 }

浙公网安备 33010602011771号