[POJ3468]线段树模板
这题WA了几次,主要有以下几个方面需要注意:
sum要+=Value*(r-l+1)
Relax时 inc(f[p*2].sum,f[p].add*(f[p*2].r-f[p*2].l+1));
program ltree; Type rec=record l,r:longint; sum,add:int64; end; Var a:array[0..100020] of int64; f:array[0..500000] of rec; n,m,i,p,q:longint; r:int64; c:char; Function max(a,b:int64):int64; begin if a>b then exit(a) else exit(b); end; Function min(a,b:int64):int64; begin if a<b then exit(a) else exit(b); end; Procedure build(P:longint); var mid:longint; begin if f[p].l=f[p].r then begin f[p].sum:=a[f[p].l]; exit; end; mid:=(f[p].l+f[p].r) div 2; f[p*2].l:=f[p].l; f[p*2].r:=mid; f[p*2+1].l:=mid+1; f[p*2+1].r:=f[p].r; build(p*2); build(p*2+1); f[p].sum:=f[p*2].sum+f[p*2+1].sum; end; Procedure relax(P:longint); begin if f[p].l=f[p].r then exit; inc(f[p*2].sum,f[p].add*(f[p*2].r-f[p*2].l+1)); inc(f[p*2].add,f[p].add); inc(f[p*2+1].sum,f[p].add*(f[p*2+1].r-f[p*2+1].l+1)); inc(f[p*2+1].add,f[p].add); f[p].add:=0; end; Function getsum(p,pl,pr:longint):int64; var mid:longint; begin if (f[p].l=pl) and (f[p].r=pr) then exit(f[p].sum); Relax(p); mid:=(f[p].l+f[p].r) div 2; getsum:=0; if pl<=mid then inc(getsum,getsum(p*2,pl,min(pr,mid))); if pr>mid then inc(getsum,getsum(p*2+1,max(pl,mid+1),pr)); end; Procedure change(p,pl,pr,v:longint); var mid:longint; begin Relax(p); if (f[p].l=pl) and (f[p].r=pr) then begin inc(f[p].sum,v*(pr-pl+1)); inc(f[p].add,v); exit; end; mid:=(f[p].l+f[p].r) div 2; if pl<=mid then change(p*2,pl,min(mid,pr),v); if pr>mid then change(p*2+1,max(mid+1,pl),pr,v); f[p].sum:=f[p*2].sum+f[p*2+1].sum; end; begin fillchar(f,sizeof(f),0); readln(n,m); for i:=1 to n do read(a[i]); readln; f[1].l:=1; f[1].r:=n; build(1); for i:=1 to m do begin read(c); case c of 'Q':begin readln(p,q); writeln(getsum(1,p,q)); end; 'C': begin readln(p,q,r); change(1,p,q,r); end; end; end; end.