区间修改区间求和cdq分治
https://www.luogu.org/problemnew/show/P3372
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) #define si(x) scanf("%d",&x) #define sl(x) scanf("%lld",&x) #define lc (d<<1) #define rc (d<<1|1) const double pi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=1e5+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; struct node{ int type,x,st; LL v; bool operator<(const node &t) const{ return x==t.x?type<t.type:x<t.x; } }q[maxn<<2],temp[maxn<<2]; LL ans[maxn]; LL pre[maxn]; void cdq(int l,int r){ if(l==r) return ; //cout<<l<<' '<<r<<endl; int mid=(l+r)>>1; cdq(l,mid);cdq(mid+1,r); int i=l,j=mid+1,p=l; LL now=0,val=0; int last=0; while(i<=mid||j<=r){ if(j>r||(i<=mid&&q[i]<q[j]) ){ now+=(q[i].x-last)*val; last=q[i].x; if(q[i].type==1) val+=q[i].v; temp[p++]=q[i++]; } else{ now+=(q[j].x-last)*val; last=q[j].x; if(q[j].type==2) ans[q[j].st]+= now*q[j].v; temp[p++]=q[j++]; } } for(int i=l;i<=r;i++) q[i]=temp[i]; } int main(){ int n,m; scanf("%d%d",&n,&m); LL xx; for(int i=1;i<=n;i++){ scanf("%lld",&xx); pre[i]=pre[i-1]+xx; } int opt,x,y; int st=0; int tot=0; LL v; for(int i=1;i<=m;i++){ scanf("%d",&opt); if(opt==1){ scanf("%d%d%lld",&x,&y,&v); q[++tot].x=x-1;q[tot].v=v;q[tot].type=1; q[++tot].x=y;q[tot].v=-v;q[tot].type=1; } else{ scanf("%d%d",&x,&y); ++st; ans[st]=pre[y]-pre[x-1]; q[++tot].x=x-1;q[tot].v=-1;q[tot].type=2;q[tot].st=st; q[++tot].x=y;q[tot].v=1;q[tot].type=2;q[tot].st=st; } } cdq(1,tot); for(int i=1;i<=st;i++) printf("%lld\n",ans[i]); }