这道题,做了好几次,彻头彻尾的经典线段树。
#include<stdio.h> #define HH 1 struct st { __int64 l; __int64 r; __int64 color; __int64 num; __int64 sum; }f[100001*4]; __int64 date[100002]; void build(__int64 l,__int64 r,__int64 n) { __int64 mid=(l+r)/2; f[n].l=l; f[n].r=r; f[n].color=0; f[n].num=0; if(l==r) { f[n].sum=date[l]; return ; } build(l,mid,n*2); build(mid+1,r,n*2+1); f[n].sum=f[n*2].sum+f[n*2+1].sum; } void down(__int64 n) { f[n].color=0; if(f[n*2].color==HH) f[n*2].num+=f[n].num; else f[n*2].num=f[n].num; if(f[n*2+1].color==HH) f[n*2+1].num+=f[n].num; else f[n*2+1].num=f[n].num; f[n*2].color=HH; f[n*2+1].color=HH; f[n*2].sum+=(f[n*2].r-f[n].l+1)*f[n].num; f[n*2+1].sum+=(f[n*2+1].r-f[n*2+1].l+1)*f[n].num; f[n].num=0; } void up(__int64 n) { f[n].sum=f[n*2].sum+f[n*2+1].sum; } void update(__int64 l,__int64 r,__int64 num,__int64 n) { __int64 mid=(f[n].l+f[n].r)/2; if(f[n].l==l&&f[n].r==r) { if(f[n].color==HH) f[n].num+=num; else f[n].num=num; f[n].color=HH; f[n].sum=f[n].sum+(f[n].r-f[n].l+1)*num; return ; } if(f[n].color==HH) down(n); if(mid>=r) update(l,r,num,n*2); else if(mid<l) update(l,r,num,n*2+1); else{ update(l,mid,num,n*2); update(mid+1,r,num,n*2+1); } up(n); } __int64 query(__int64 l,__int64 r,__int64 n) { __int64 mid=(f[n].l+f[n].r)/2,cos=0; if(f[n].l==l&&f[n].r==r) { // printf("%d %d %d %d..\n",f[n].l,f[n].r,f[n].num,f[n].sum); return f[n].sum; } if(f[n].color==HH) down(n); if(mid>=r) cos+=query(l,r,n*2); else if(mid<l) cos+=query(l,r,n*2+1); else { cos+=query(l,mid,n*2); cos+=query(mid+1,r,n*2+1); } return cos; } int main() { __int64 i,j,n,t,q,l,r,num; __int64 k; char c[10]; while(scanf("%I64d%I64d",&n,&q)>0) { for(i=1;i<=n;i++) scanf("%I64d",&date[i]); build(1,n,1); getchar(); while(q--) { scanf("%s",c); if(c[0]=='Q') { scanf("%I64d%I64d",&l,&r); k=query(l,r,1); printf("%I64d\n",k); } else if(c[0]=='C') { scanf("%I64d%I64d%I64d",&l,&r,&num); update(l,r,num,1); } } } return 0; }
过的时间还是比较多,要改进才行。