[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.

浙公网安备 33010602011771号