线段树统计树

来源:互联网 发布:淘宝的延长收货是几天 编辑:程序博客网 时间:2024/04/30 06:04

一行N个方格,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤1024,提问和修改的总数可能达到60000条。

 

分析:为线段树每个节点增加一个Count域。表示所对应区间内元素之和。每次修改一个格子,需要修改从叶结点到根结点路径上所有结点的值。

 

const

 maxn=100000;

type

 treenode=record

            flag:integer;

            count:integer;

          end;

var

 tree:array[1..4*maxn] of treenode;

 n,k:integer;

 

procedure init;

begin

 readln(n);

 k:=0;

end;

 

procedure create(p,l,r:integer);

var

 m:integer;

begin

 m:=(l+r) div 2;

  ifr-l=1 then begin

                  inc(k);

                  tree[p].flag:=k;

                  exit;

                end;

 create(p*2,l,m);

 create(p*2+1,m,r);

end;

 

procedure find(p,l,r,x:integer;varpos:integer);

var

 m:integer;

begin

 m:=(l+r) div 2;

  if(r-l=1)

   then begin

         if (tree[p].flag=x)

           then pos:=p;

         exit;

        end;

 find(p*2,l,m,x,pos);

 find(p*2+1,m,r,x,pos)

end;

 

procedure modify(p,delta:integer);

begin

 repeat

   tree[p].count:=tree[p].count+delta;

   p:=p div 2;

 until p=0;

end;

 

function count(p,l,r,a,b:integer):integer;

var

 m:integer;

begin

  if(l=a) and (r=b)

   then count:=tree[p].count

   else begin

          m:=(l+r) div 2;

          if b<=m

            then count:=count(p*2,l,m,a,b)

            else if a>=m then count:=count(p*2+1,m,r,a,b)

                          elsecount:=count(p*2,l,m,a,m)+count(p*2+1,m,r,m,b);

        end

end;

 

procedure main;

var

 i,l,a,b,p:integer;

 ch:char;

begin

 readln(l);

  fori:=1 to l do

   begin

     read(ch);

     case ch of

       'c':begin

              readln(a,b);

              writeln(count(1,1,maxn,a,b+1));

           end;

       'm':begin

              readln(a,b);

              find(1,1,maxn,a,p);

              modify(p,b);

           end;

     end;

   end;

end;

 

begin

 init;

 create(1,1,maxn);

 main;

end.

0 0