• poj3321


    树映射到树状数组上

    非常好的题目,给了我很多启发

    题目要求动态求一个棵子树的节点个数

    不禁联想到了前缀和,只要我们能用一个合适的优先级表示每个顶点,那么就好做了

    我们可以考虑将子树表示成区间的形式

    这个子树的根节点显然是区间的右端点,那么左端点一定是子树中编号最小的那个

    这样问题就转化为区间求和,单点修改的问题了

    很容易想到树状数组

    我们可以用后序遍历树,这样映射到树状数组之后就好办了

     1 type link=^node;
     2      node=record
     3        po:longint;
     4        next:link;
     5      end;
     6 var w:array[0..100100] of link;
     7     c,h,f,a:array[0..100100] of longint;
     8     v:array[0..100100] of boolean;
     9     t,r,n,m,i,x,y:longint;
    10     ch:char;
    11 
    12 function lowbit(x:longint):longint;
    13   begin
    14     exit(x and (-x));
    15   end;
    16 
    17 procedure add(x,y:longint);
    18   var p:link;
    19   begin
    20     new(p);
    21     p^.po:=y;
    22     p^.next:=w[x];
    23     w[x]:=p;
    24   end;
    25 
    26 procedure dfs(i:longint);    //映射
    27   var tmp,y:longint;
    28       p:link;
    29   begin
    30     v[i]:=true;
    31     p:=w[i];
    32     tmp:=n+1;
    33     while p<>nil do
    34     begin
    35       y:=p^.po;
    36       if not v[y] then
    37       begin
    38         dfs(y);
    39         if tmp>f[y] then tmp:=f[y];
    40       end;
    41       p:=p^.next;
    42     end;
    43     inc(t);
    44     h[i]:=t;
    45     if tmp<>n+1 then
    46       f[i]:=tmp
    47     else f[i]:=h[i];
    48   end;
    49 
    50 procedure work(x,f:longint);
    51   begin
    52     while x<=n do
    53     begin
    54       c[x]:=c[x]+f;
    55       x:=x+lowbit(x);
    56     end;
    57   end;
    58 
    59 function ask(x:longint):longint;
    60   begin
    61     ask:=0;
    62     while x>0 do
    63     begin
    64       ask:=ask+c[x];
    65       x:=x-lowbit(x);
    66     end;
    67   end;
    68 
    69 begin
    70   readln(n);
    71   for i:=1 to n-1 do
    72   begin
    73     readln(x,y);
    74     add(x,y);
    75     add(y,x);
    76     a[i]:=1;
    77   end;
    78   a[n]:=1;
    79   dfs(1);
    80   for i:=1 to n do
    81     work(i,1);
    82   readln(m);
    83   for i:=1 to m do
    84   begin
    85     readln(ch,r);
    86     if ch='Q' then
    87     begin
    88       x:=f[r];
    89       y:=h[r];
    90       writeln(ask(y)-ask(x-1));
    91     end
    92     else begin
    93       x:=h[r];
    94       if a[x]=0 then work(x,1)   //细节题目要求没苹果的时候加苹果
    95       else work(x,-1);
    96       a[x]:=a[x] xor 1;
    97     end;
    98   end;
    99 end.
    View Code

    type link=^node;

         node=record

           po:longint;

           next:link;

         end;

    var w:array[0..100100] of link;

        c,h,f,a:array[0..100100] of longint;

        v:array[0..100100] of boolean;

        t,r,n,m,i,x,y:longint;

        ch:char;

     

    function lowbit(x:longint):longint;

      begin

        exit(x and (-x));

      end;

     

    procedure add(x,y:longint);

      var p:link;

      begin

        new(p);

        p^.po:=y;

        p^.next:=w[x];

        w[x]:=p;

      end;

     

    procedure dfs(i:longint);    //映射

      var tmp,y:longint;

          p:link;

      begin

        v[i]:=true;

        p:=w[i];

        tmp:=n+1;

        while p<>nil do

        begin

          y:=p^.po;

          if not v[y] then

          begin

            dfs(y);

            if tmp>f[y] then tmp:=f[y];

          end;

          p:=p^.next;

        end;

        inc(t);

        h[i]:=t;

        if tmp<>n+1 then

          f[i]:=tmp

        else f[i]:=h[i];

      end;

     

    procedure work(x,f:longint);

      begin

        while x<=n do

        begin

          c[x]:=c[x]+f;

          x:=x+lowbit(x);

        end;

      end;

     

    function ask(x:longint):longint;

      begin

        ask:=0;

        while x>0 do

        begin

          ask:=ask+c[x];

          x:=x-lowbit(x);

        end;

      end;

     

    begin

      readln(n);

      for i:=1 to n-1 do

      begin

        readln(x,y);

        add(x,y);

        add(y,x);

        a[i]:=1;

      end;

      a[n]:=1;

      dfs(1);

      for i:=1 to n do

        work(i,1);

      readln(m);

      for i:=1 to m do

      begin

        readln(ch,r);

        if ch='Q' then

        begin

          x:=f[r];

          y:=h[r];

          writeln(ask(y)-ask(x-1));

        end

        else begin

          x:=h[r];

          if a[x]=0 then work(x,1)   //细节题目要求没苹果的时候加苹果

          else work(x,-1);

          a[x]:=a[x] xor 1;

        end;

      end;

    end.

     

     

  • 相关阅读:
    【Gstreamer开发】TI嵌入式处理器GStreamer pipeline
    【Gstreamer开发】TI嵌入式处理器GStreamer pipeline
    【ARM-LInux开发】利用scp 远程上传下载文件/文件夹
    【ARM-LInux开发】利用scp 远程上传下载文件/文件夹
    【VS开发】ClientToScreen 和ScreenToClient 用法
    【VS开发】ClientToScreen 和ScreenToClient 用法
    【C/C++开发】C中调用C++函数
    【C/C++开发】C中调用C++函数
    【C/C++开发】字符串操作
    【C/C++开发】字符串操作
  • 原文地址:https://www.cnblogs.com/phile/p/4473270.html
Copyright © 2020-2023  润新知