线段树成段更新。成段求和
開始没有注意到更新的值能够是负数。结果吧标记初始化为-1。wa到死
#include<iostream> #include<cstdio> #define maxn 111111 #define ll long long using namespace std; ll num[maxn]; int n,m; string cmd; int a,b,k; struct stu { int l,r,m; ll sum,flag; ll len() { return r-l+1; } }; stu mapp[maxn*4]; void pushdown(int count) { if(mapp[count].flag!=0) { mapp[count*2].flag+=mapp[count].flag; mapp[count*2+1].flag+=mapp[count].flag; mapp[count*2].sum+=mapp[count].flag*mapp[count*2].len(); mapp[count*2+1].sum+=mapp[count].flag*mapp[count*2+1].len(); mapp[count].flag=0; } } void build(int l,int r,int count) { mapp[count].l=l; mapp[count].r=r; mapp[count].m=(l+r)/2; mapp[count].flag=0; if(l==r) { mapp[count].sum=num[l]; return; } build(l,(l+r)/2,count*2); build((l+r)/2+1,r,count*2+1); mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; } void updata(int l,int r,int count) { if(mapp[count].l==l&&mapp[count].r==r) { mapp[count].flag+=k; mapp[count].sum+=mapp[count].len()*k; return; } pushdown(count); if(r<=mapp[count].m) updata(l,r,count*2); else if(l>=mapp[count].m+1) updata(l,r,count*2+1); else { updata(l,mapp[count].m,count*2); updata(mapp[count].m+1,r,count*2+1); } mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; //cout<<mapp[count].l<<"~"<<mapp[count].r<<"~"<<mapp[count].sum<<endl; } long long que(int l,int r,int count) { if(mapp[count].l==l&&mapp[count].r==r) return mapp[count].sum; pushdown(count); if(r<=mapp[count].m) return que(l,r,count*2); else if(l>=mapp[count].m+1) return que(l,r,count*2+1); else { return que(l,mapp[count].m,count*2)+que(mapp[count].m+1,r,count*2+1); } //cout<<mapp[count].l<<"~"<<mapp[count].r<<"~"<<mapp[count].sum<<endl; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%I64d",&num[i]); } build(1,n,1); for(int i=0;i<m;i++) { cin>>cmd; if(cmd=="Q") { scanf("%d%d",&a,&b); printf("%I64d ",que(a,b,1)); } else { scanf("%d%d%d",&a,&b,&k); updata(a,b,1); } } } return 0; }