树映射到树状数组上

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

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

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

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

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

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

很容易想到树状数组

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

 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. Spark Streaming揭秘 Day10 从BlockGenerator看接收数据的生命周期

    Spark Streaming揭秘 Day10 从BlockGenerator看接收数据的生命周期 昨天主要介绍了SparkStreaming中对于Receiver的生命周期管理,下面让我们进入到Re ...

  2. Describe the difference between repeater, bridge and router.

    中继器,路由器,网桥,网关的区别. 路由器:网络层设备,实现复杂的路径选择,控制IP包从源到目的地的路径:根据IP地址进行选路和转发IP数据包 中继器:物理层设备,物理信号的重新生成,对信号进行整形和 ...

  3. Cadence封装制作之表贴封装的制作

    以0805封装为例 1.打开PCB editor-> Allegro PCB Design XL 2.File -> New ① Drawing Type -> Package Sy ...

  4. PHP微信开发代码

    1,SAE上申请服务器 2,绑定测试账号 3,Token验证 <?php /* http://www.cnblogs.com/xrhou12326/ CopyRight 2014 All Rig ...

  5. 使用泛型 类型“System.Collections.Generic.IEnumerator<T>”需要 1 个类型参数

    解决办法:添加 using System.Collections:命名空间

  6. W25Q32的使用

    一.W25Q32简介 W25Q32是华邦公司推出的大容量“SPI  FLASH” 产品. 1.容量 32M-Bit/4M-byte(4,194,304) 2.存储结构 页:256-bytes 扇区:4 ...

  7. C语言基础(转载自大海笔记)

    # C语言基础2015年03月26日10:04:411.    语言排行榜C——java——objective-C2.    进制:进制:进位机制.用普通的话讲,应该为人为的定义一种度量来标识一样东西 ...

  8. Delphi与Qt在Windows下使用共享内存进程间通信

    Delphi部分 type  TGuardInfo=record    Lock: Integer;  end;  PGuardInfo = ^TGuardInfo; TGuardShareMem=c ...

  9. ionicPopup确认对话框

    $ionicPopup.confirm({ title: $rootScope.app_name, template: 'Do you want to add this to database?', ...

  10. 使用Compass制作雪碧图

    遇见好的文章,笔者也会转载.但是正所谓好记性不如烂笔头,单纯的拿来主义也不如自己的亲自实践.所以每次需要转载的文章,我都会自己敲一遍,中间加入一些自己的思考. 这篇文章转载自:http://www.h ...