[Poj]3321——DFS+树状数组

[题目大意]
  • 给定一棵有根树,可以对结点值进行操作,+1或是-1,不断询问一个子树上的值的总和

[分析题解]
  •  经典的DFS序+树状数组“变点问间”式维护
  • 这不是重点,重点在于写的手工栈,相比一年之前代码素养有了明显的提高,相信再做那个题,再也不会出现某个点40S出解导致一直不停的TLE的情况了>_<

[个人代码]
View Code
  1 //10150334      perseawe        3321    Accepted        4620K   235MS   Pascal  2043B   2012-05-03 22:05:03
  2 
  3 Var
  4   ch:char;
  5   N,M,tot,u,v,i,x,time:Longint;
  6   Use,Have:Array [0..100000+1000of Boolean;
  7   Stack,L,R,hv,tree:Array [0..100000+1000of Longint;
  8   Edge:Array [0..200000+2000of Record wh,next:Longint;end;
  9 
 10 Procedure AddEdge(u,v:Longint);
 11   begin
 12     inc(tot);
 13     Edge[tot].next:=hv[u];hv[u]:=tot;
 14     Edge[tot].wh:=v;
 15     inc(tot);
 16     Edge[tot].next:=hv[v];hv[v]:=tot;
 17     Edge[tot].wh:=u;
 18   end;
 19 
 20 Procedure DFS;
 21   var
 22     u,v,top:Longint;
 23   begin
 24     time:=1;
 25     Fillchar(Use,Sizeof(Use),False);Use[1]:=True;
 26     top:=1;Stack[top]:=1;
 27     Repeat
 28       u:=Stack[top];
 29       if L[u]=0 then L[u]:=time;
 30       while hv[u]<>0 do
 31         begin
 32           v:=Edge[hv[u]].wh;
 33           if not(use[v]) then
 34             begin
 35               Use[v]:=True;
 36               Inc(time);
 37               Inc(top);
 38               Stack[top]:=v;
 39               Break;
 40             end;
 41           hv[u]:=Edge[hv[u]].next;
 42         end;
 43       if hv[u]=0 then begin R[u]:=Time;dec(top);end;
 44     Until top=0;
 45   end;
 46 
 47 Procedure Add(p,x:Longint);
 48   begin
 49     While not(p>time) do
 50       begin
 51         inc(tree[p],x);
 52         inc(p,p and -p);
 53       end;
 54   end;
 55 
 56 
 57 Procedure Change(p,L,R:Longint);
 58   begin
 59     if have[p] then Add(L,-1else Add(L,1);
 60     have[p]:=not(have[p]);
 61   end;
 62 
 63 Function GetSum(p:Longint):Longint;
 64   var
 65     Res:Longint;
 66   begin
 67     Res:=0;
 68     While not(p=0do
 69       begin
 70         Inc(Res,tree[p]);
 71         Dec(p,p and -p);
 72       end;
 73     Exit(Res);
 74   end;
 75 
 76 Function Ask(L,R:Longint):Longint;
 77   begin
 78     exit(GetSum(R)-GetSum(L-1));
 79   end;
 80 
 81 Begin
 82   Assign(Input,'P3321.in');Reset(INPUT);
 83   readln(N);
 84   tot:=0;
 85   Fillchar(hv,sizeof(hv),0);
 86   for i:=1 to n-1 do
 87     begin
 88       readln(u,v);
 89       AddEdge(u,v);
 90     end;
 91 
 92   DFS;
 93   Fillchar(tree,sizeof(tree),0);
 94   Fillchar(have,sizeof(have),False);
 95   for i:=1 to N do change(i,L[i],R[i]);
 96 
 97   readln(M);
 98   for i:=1 to M do
 99     begin
100       readln(ch,x);
101       if ch='C' then change(x,L[x],R[x]) else writeln(Ask(L[x],R[x]));
102     end;
103   Close(INPUT);
104 End.

[相关链接] 
  1.  

[启发总结]
  1.  
posted @ 2012-05-03 22:25  PerSeAwe  阅读(331)  评论(0编辑  收藏  举报