树映射到树状数组上

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

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

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

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

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

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

很容易想到树状数组

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

 type link=^node;
     node=record
       po:longint;
       next:link;
     end;
var w:array[..] of link;
    c,h,f,a:array[..] of longint;
    v:array[..] 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+;
    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+ 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:=;
    while x> do
    begin
      ask:=ask+c[x];
      x:=x-lowbit(x);
    end;
  end; begin
  readln(n);
  for i:= to n- do
  begin
    readln(x,y);
    add(x,y);
    add(y,x);
    a[i]:=;
  end;
  a[n]:=;
  dfs();
  for i:= to n do
    work(i,);
  readln(m);
  for i:= to m do
  begin
    readln(ch,r);
    if ch='Q' then
    begin
      x:=f[r];
      y:=h[r];
      writeln(ask(y)-ask(x-));
    end
    else begin
      x:=h[r];
      if a[x]= then work(x,)   //细节题目要求没苹果的时候加苹果
      else work(x,-);
      a[x]:=a[x] xor ;
    end;
  end;
end.

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.

poj3321的更多相关文章

  1. poj3321 dfs序+树状数组单点更新 好题!

    当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题 树的dfs序映射在树状数组上进行单点修改,区间查询. /* 树状数组: lowbit[i] = i&-i C[i] = a[i-l ...

  2. POJ3321 Apple Tree (JAVA)

    树形数组题,有一定难度. 首先得搞清楚树形数组是什么 - 它是建立在原始数组上的统计数组 - 目的:方便对原始数组进行切片统计,主要用于统计切片的累加和 其实你可以对切片进行扫描,把元素一个一个加起来 ...

  3. poj3321(dfs序+树状数组)

    题目链接:https://vjudge.net/problem/POJ-3321 题意:给一个普通树(不是二叉树),并且已经编号,每个结点为1或0,有两种操作,对单个结点修改和查询一个结点的子树的所有 ...

  4. 【POJ3321】Apple Tree(DFS序,树状数组)

    题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000   思路:最近一段时间在思考树上统计问题的算法 发 ...

  5. [poj3321]Apple Tree_dfs序_树状数组

    Apple Tree poj-3321 题目大意:给你一个根固定的树,每一个点的点权是0或1,查询子树点权和. 注释:$1\le n \le 10^5$. 想法:刚刚学习dfs序,刷到水题偶哈哈. 什 ...

  6. POJ3321 Apple Tree(树状数组)

    先做一次dfs求得每个节点为根的子树在树状数组中编号的起始值和结束值,再树状数组做区间查询 与单点更新. #include<cstdio> #include<iostream> ...

  7. [poj3321]Apple Tree(dfs序+树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Descr ...

  8. POJ3321 Apple Tree(DFS序)

    题目,是对一颗树,单点修改.子树查询.典型的dfs序入门题. DFS序可以将一颗树与子树们表示为一个连续的区间,然后用线段树来维护:感觉算是树链剖分的一种吧,和轻重链剖分不同的是这是对子树进行剖分的. ...

  9. POJ3321 Apple Tree (树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16180   Accepted: 4836 Descr ...

随机推荐

  1. fragment第二次载入就报错

    1.布局中加入一个<fragment 标签,第一次载入的时候是正常的,第二次加载的时候,就直接crashed,退出 2.查到原因Caused by: java.lang.IllegalArgum ...

  2. MenuItem

    private void 文件ToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("打开测试" ...

  3. Java - 选择性排序 PHP || Java 代码对比

    int [] array1 = {1,3,5,7,9,10,2,15,154,10,2,188,200};//定义一个数组,内容为混乱大小 int index = 0;//定义一个最大值或最小值的位置 ...

  4. PHP webserver 之 soap wsdl

    强势插入:http://pan.baidu.com/s/1jG62oKm

  5. mac系统在控制台中ping网址提示不能解析host

    更换dns就好了 系统偏好设置——网络——dns 换成 8.8.8.8 114.114.114.114 也可以参考v2ex的dns http://www.guomii.com/posts/5315

  6. ng-blur失去焦点执行事件

    <label class="item item-input item-stacked-label"> <span class="input-label& ...

  7. Apache URL rewrite 配置

    下面是Apache的配置过程,可以参考下:1.httpd.conf配置文件中加载了mod_rewrite.so模块,使用虚拟主机 #LoadModule rewrite_module modules/ ...

  8. Akka学习——术语和概念

    (大部分为翻译) Concurrency vs. Parallelism 并发 vs 并行   并发并不一定同时运行,比如使用时间片,使得两个任务交替执行.而并行是执两个任务真正的同时执行.     ...

  9. 让wordpress投稿作者在后台只看到自己的文章

    wordpress支持多作者撰写,让更多的人参与网站内容的创建是个不错的想法,UGC(User-generated content)使网站主题更丰富,不同的内容吸引不同的受众,一个好的网站应该多产生U ...

  10. js 计时器

    <html><head><script type="text/javascript">var count=0;var t ;function t ...