树映射到树状数组上

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

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

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

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

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

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

很容易想到树状数组

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

 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. java----线程篇

    一个线程是进程内的一个单一的顺序控制流程图,多线程是指一个进程可以同时运行几个任务,每个任务由一个线程来完成.即多个线程可以同时运行,并且在一个进程内执行不同的任务. 1.创建线程两种方法方法一, 继 ...

  2. CentOS7下源码安装mysql5.6

    目录 准备工作 运行环境 确认你的安装版本 下载mysql 安装mysql 准备安装环境 编译和安装 配置mysql 单实例配置      单实例配置方法          添加防火墙         ...

  3. JavaScript 常用方法总结

    经常使用的 JS 方法,今天记下,以便以后查询 /* 手机类型判断 */ var BrowserInfo = { userAgent: navigator.userAgent.toLowerCase( ...

  4. Arcgis 10.1中空间连接功能

    空间链接的作用:将面上的所有点的值加起来取平均值.赋值给面属性.(我们可以定义右击——定义合并规则 连接要素的字段映射参数中指定的合并规则仅适用于连接要素中的属性,且仅适用于多个要素与目标要素匹配 ( ...

  5. python总字符串

    前面我们讲解了什么是字符串.字符串可以用''或者""括起来表示. 如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示 ...

  6. (转)汇编bne的问题

    网址:http://blog.csdn.net/lwj103862095/article/details/8073571 memsetup:    @ 设置存储控制器以便使用SDRAM等外设 mov ...

  7. Castle ActiveRecord简单介绍

    Castle ActiveRecord框架是一个基于.NET的ORM框架,它实现了ActiveRecord设计模式.它本身就是基于NHibernate,只是封 装了NHibernate的大部分烦杂细节 ...

  8. poj 3522 Slim Span (最小生成树kruskal)

    http://poj.org/problem?id=3522 Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions ...

  9. 3111: [Zjoi2013]蚂蚁寻路 - BZOJ

    题目描述 Description在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长.蚂蚁转弯是有一定 ...

  10. XML 创建

    using unityEngine; using System.Collections; using System.Linq; using System.Xml.Linq; using System; ...