线段树模板
#include<cstdio> #define N 200100 int n,Q,tot=0,x; long long a[200100]; struct tree { int left,right; int rptr,lptr; long long sum; long long bj; }t[N*4]; void buildtree(int ll,int rr) { int cur=++tot; t[cur].left=ll; t[cur].right=rr; if (ll+1!=rr) { t[cur].lptr=tot+1; buildtree(ll,(ll+rr)/2); t[cur].rptr=tot+1; buildtree((ll+rr)/2,rr); t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum; } else t[cur].sum=a[ll]; } void update(long long k) { t[t[k].lptr].sum+=(t[t[k].lptr].right-t[t[k].lptr].left)*t[k].bj; t[t[k].rptr].sum+=(t[t[k].rptr].right-t[t[k].rptr].left)*t[k].bj; t[t[k].lptr].bj+=t[k].bj; t[t[k].rptr].bj+=t[k].bj; t[k].bj=0; } void change(int k,int ll,int rr,long long delta) { if (ll<=t[k].left&&rr>=t[k].right) { t[k].sum+=(t[k].right-t[k].left)*delta; t[k].bj+=delta; } else { if (t[k].bj) update(k); if (ll<(t[k].left+t[k].right)/2) change(t[k].lptr,ll,rr,delta); if (rr>(t[k].left+t[k].right)/2) change(t[k].rptr,ll,rr,delta); t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum; } } long long find(int k,int ll,int rr) { if (ll<=t[k].left&&rr>=t[k].right) return t[k].sum; long long ans=0; if (t[k].bj) update(k); if (ll<(t[k].left+t[k].right)/2) ans+=find(t[k].lptr,ll,rr); if (rr>(t[k].left+t[k].right)/2) ans+=find(t[k].rptr,ll,rr); return ans; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lld",&a[i]); buildtree(1,n+1);//注意由于区间是左闭右开,所以右边的数加一,下同 scanf("%d",&Q); for (int i=1;i<=Q;i++) { int f; scanf("%d",&f); if (f==1) { int a,b; scanf("%d%d%lld",&a,&b,&x); change(1,a,b+1,x); } else { int a,b; scanf("%d%d",&a,&b); printf("%lld\n",find(1,a,b+1));//别忘了换行 } } return 0; }
时间: 2024-10-08 19:35:06