那天考完,不知道怎么谈到zkw树的区间修改。于是就重温了一下zkw那坑爹的ppt...果断晕了,后来问了HUC才知道是差分。。。
维护两棵树,i*Ai,与Ai-A(I-1)
贴代码
const
find=131071;
var
tree:array[1..2,0..2662144]of int64;
a:array[0..100001]of int64;
m,n:longint;
procedure change(k,x:longint;w:int64);
var
k1:longint;
begin
x:=x+find;
tree[k,x]:=tree[k,x]+w;
k1:=x shr 1;
while k1>0 do
begin
tree[k,k1]:=tree[k,k1]+w;
k1:=k1 shr 1;
end;
end;
function ask(k,x,y:longint):int64;
begin
x:=x+find-1; y:=y+find+1;
ask:=0;
while not (x xor y=1) do
begin
if x and 1=0 then ask:=ask+tree[k,x+1];
if y and 1=1 then ask:=ask+tree[k,y-1];
x:=x shr 1; y:=y shr 1;
end;
exit(ask);
end;
procedure init;
var
i:longint;
begin
readln(n,m);
fillchar(tree,sizeof(tree),0);
for i:=1 to n do read(a[i]);
for i:=1 to n do
begin
change(1,i,a[i]-a[i-1]);
change(2,i,i*(a[i]-a[i-1]));
end;
readln;
end;
procedure main;
var
i,x,y:longint;
x1,ans1,ans2:int64;
z1,z2:char;
begin
for i:=1 to m do
begin
read(z1,z2,x,y);
if z1='Q' then
begin
x:=x-1;
ans1:=ask(1,1,y)*(y+1);
ans1:=ans1-ask(2,1,y);
if x<>0 then
begin
ans2:=ask(1,1,x)*(x+1);
ans2:=ans2-ask(2,1,x);
end else ans2:=0;
writeln(ans1-ans2);
end
else
begin
read(x1);
change(1,x,x1); change(1,y+1,-x1);
change(2,x,x*x1); change(2,y+1,-(y+1)*x1)
end;
readln;
end;
end;
begin
init;
main;
end.