思路:線段樹模板題,用add標記。具體內容可參考代碼或者劉汝佳訓練指南。
#include<cstdio> #include<cstring> #define MAXN 100005 typedef long long LL; LL n,Q,ql,qr,v,sumv[MAXN*3],a[MAXN],addv[MAXN*3],_sum; char op; void build(LL o,LL L,LL R) { if(L==R) {sumv[o]=a[L];return;} LL M=(L+R)>>1; build(o*2,L,M); build(o*2+1,M+1,R); sumv[o]=sumv[o*2]+sumv[o*2+1];//維護根節點 } void query(LL o,LL L,LL R,LL add) { if(ql<=L && R<=qr) {_sum+=add*(R-L+1)+sumv[o];return;} LL M=(L+R)>>1; if(ql<=M)query(o*2,L,M,add+addv[o]); if(M<qr)query(o*2+1,M+1,R,add+addv[o]); } void update(LL o,LL L,LL R) { if(ql<=L && R<=qr) {addv[o]+=v;sumv[o]+=v*(R-L+1);return;} LL M=(L+R)>>1; if(ql<=M) update(o*2,L,M); if(qr>M) update(o*2+1,M+1,R); sumv[o]=sumv[o*2]+sumv[o*2+1]+addv[o]*(R-L+1); } int main() { while(~scanf("%I64d%I64d",&n,&Q)) { for(LL i=1;i<=n;++i) scanf("%I64d",&a[i]); memset(addv,0,sizeof(addv)); build(1,1,n); while(Q--) { getchar(); op=getchar(); if(op=='Q') { scanf("%I64d%I64d",&ql,&qr); _sum=0; query(1,1,n,0); printf("%I64d\n",_sum); } else { scanf("%I64d%I64d%I64d",&ql,&qr,&v); update(1,1,n); } } } return 0; }
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。