poj 3321 Apple Tree 树状数组

题意:有一颗苹果树,树上有n个节点,每个节点最多有一个苹果。一开始,每个节点上有一个苹果。定义操作Q i为询问以节点i为根节点的子树上有多少个苹果,C i为改变节点i的苹果数(原来为1,则变为0,反之相反)最多有100000个节点。


分析:先进行一次dfs,把每个节点的dfs序记录下来,那么就把树转换成了一个序列。很容易得知一个节点的子树一定是该序列的一个子序列,那么剩下的就是裸的树状数组了。


代码:

const
  maxn=100000;

var
  e,n,dep,root:longint;
  num,l,r,last,v,a:array[1..maxn] of longint;
  side:array[1..maxn] of record
    x,y,next:longint;
  end;

procedure add(x,y:longint);
begin
  inc(e);
  side[e].x:=x; side[e].y:=y; side[e].next:=last[x]; last[x]:=e;
end;

procedure init;
var
  i,x,y:longint;
begin
  readln(n);
  fillchar(v,sizeof(v),0);
  for i:=1 to n-1 do
  begin
    readln(x,y);
    add(x,y);
    v[y]:=1;
  end;
  for i:=1 to n do
    if v[i]=0 then
    begin
      root:=i;
      break;
    end;
end;

function max(x,y:longint):longint;
begin
  if x>y then exit(x)
         else exit(y);
end;

function min(x,y:longint):longint;
begin
  if x<y then exit(x)
         else exit(y);
end;

function lowbit(x:longint):longint;
begin
  lowbit:=x and -x;
end;

procedure dfs(x:longint);
var
  i:longint;
begin
  inc(dep);
  num[x]:=dep;
  l[x]:=dep;
  r[x]:=dep;
  i:=last[x];
  while i>0 do
    with side[i] do
    begin
      dfs(y);
      l[x]:=min(l[x],l[y]);
      r[x]:=max(r[x],r[y]);
      i:=next;
    end;
end;

procedure updata(x,delta:longint);
var
  i:longint;
begin
  i:=x;
  while i<=n do
  begin
    a[i]:=a[i]+delta;
    i:=i+lowbit(i);
  end;
end;

function sum(x:longint):longint;
var
  i:longint;
begin
  sum:=0;
  i:=x;
  while i>0 do
  begin
    sum:=sum+a[i];
    i:=i-lowbit(i);
  end;
end;

procedure main;
var
  m,i,x,delta:longint;
  c:char;
begin
  dfs(root);
  for i:=1 to n do
  begin
    a[i]:=lowbit(i);
    v[i]:=1;
  end;
  readln(m);
  for i:=1 to m do
  begin
    read(c);
    if c='C'
      then begin
             readln(x);
             if v[x]=1
               then delta:=-1
               else delta:=1;
             v[x]:=1-v[x];
             updata(num[x],delta);
           end
      else begin
             readln(x);
             writeln(sum(r[x])-sum(l[x]-1));
           end;
  end;
end;

begin
  init;
  main;
end.


你可能感兴趣的:(poj 3321 Apple Tree 树状数组)