poj 3468:zkw树区间修改

那天考完,不知道怎么谈到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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值