POJ 3321 Apple Tree (DFS + 树状数组)
题意:
一棵苹果树有N个分叉,编号1---N(根的编号为1),每个分叉只能有一颗苹果或者没有苹果。 现在有两种操作:
1.某个分叉上的苹果从有变无或者从无边有。
2.需要统计以某个分叉为根节点时,它的子树上(包括该分叉)共有多少苹果。
分析: 有两种操作,基本就是使用数据结构维护的题目了。开始想了很久,不懂如何将分叉转化为一维线性的树状数组维护。 看了下discuss,有人说了时间戳三字。想了想,发现如果按照节点遍历的顺序可以制造出时间上的线性关系。 例如:
连接情况为:1---->2 1--->3 3--->4 3--->5
以1为根节点开始dfs,则遍历到每个点的时间可以为 1---->1 3--->2 4--->3 5---->4 2--->5
用两个数组begin,end统计以节点i为根时,遍历的第一个点的时间,和遍历最后一个点的时间
所以:begin[1] = 1 ; end[1] = 5; begin[2] = 5 ; end[2] = 5; begin[3] = 2; end[3] = 4;........................................................
改变节点i的状态,时间戳小于i的会受影响;求和时,只需求(begin[i],end[i])的和了............................这样就变成了单点更新,区间求和的问题了。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
#define MAX 100005
#define INF 0x7FFFFFFF
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std; int begin[MAX],end[MAX],cnt[MAX],vis[MAX];
int c[MAX];
int n,m,step;
char op;
struct node {
int s,e,next;
} ed[MAX];
int head[MAX],num; void init() {
memset(head,-1,sizeof(head));
num = 0;
step = 1;
memset(c,0,sizeof(c));
memset(cnt,1,sizeof(cnt));
memset(vis,0,sizeof(vis));
} void addedge(int s,int e) {
ed[num].s = s;
ed[num].e = e;
ed[num].next = head[s];
head[s] = num ++;
} int lowbit(int x) {
return x & (-x);
} void update(int x,int va) {
while(x > 0) {
c[x] += va;
x -= lowbit(x);
}
} int query(int x) {
int sum = 0;
while(x <= n) {
sum += c[x];
x += lowbit(x);
}
return sum;
} void dfs(int v0) {
vis[v0] = 1;
begin[v0] = step;
for(int i=head[v0]; i != -1; i = ed[i].next) {
int e = ed[i].e;
if(vis[e] == 0) {
step ++;
dfs(e);
}
}
end[v0] = step;
} int main() {
init();
scanf("%d",&n);
int x,y;
for(int i=0; i<n-1; i++) {
scanf("%d%d",&x,&y);
addedge(x,y);
}
dfs(1);
for(int i=1; i<=n; i++) update(i,1);
scanf("%d",&m);
for(int i=0; i<m; i++) {
getchar();
scanf("%c%d",&op,&x);
if(op == 'Q') {
printf("%d\n",query(begin[x]) - query(end[x] + 1));
}
if(op == 'C') {
cnt[x] ++;
if(cnt[x] % 2 == 0) update(begin[x],-1);
else update(begin[x],1);
}
}
return 0;
}
POJ 3321 Apple Tree (DFS + 树状数组)的更多相关文章
- POJ 3321 Apple Tree 【树状数组+建树】
题目链接:http://poj.org/problem?id=3321 Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submiss ...
- poj 3321:Apple Tree(树状数组,提高题)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 5629 Descr ...
- poj 3321 Apple Tree(一维树状数组)
题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...
- POJ 3321 Apple Tree(树状数组)
点我看题目 题意 : 大概是说一颗树有n个分岔,然后给你n-1对关系,标明分岔u和分岔v是有边连着的,然后给你两个指令,让你在Q出现的时候按照要求输出. 思路 :典型的树状数组.但是因为没有弄好数组 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- POJ - 3321 Apple Tree (线段树 + 建树 + 思维转换)
id=10486" target="_blank" style="color:blue; text-decoration:none">POJ - ...
- POJ 3321 Apple Tree DFS序 + 树状数组
多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...
- (简单) POJ 3321 Apple Tree,树链剖分+树状数组。
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...
- POJ3321 Apple Tree (树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16180 Accepted: 4836 Descr ...
随机推荐
- centos单用户模式:修改ROOT密码和grub加密
centos单用户模式:修改ROOT密码和grub加密 CentOSLinux网络应用配置管理应用服务器 Linux 系统处于正常状态时,服务器主机开机(或重新启动)后,能够由系统引导器程序自动引导 ...
- Clash of Clans(COC)资源压缩解密
Clash of Clans,简称为COC,中文名<部落冲突>,是ios平台上一款相当火爆的战斗策略类游戏,开发商是芬兰的supercell,据说日收入上百万美刀,创造了手游史上的一个神话 ...
- MySQL5.6 windows7下安装及基本操作
图形界面安装MySQL5.6关于图形界面的安装,网上相关相关资料比较多,此处省略安装过程.安装过程中选择安装路径.所需组件及root账号密码.1.目前针对不同用户,MySQL提供了2个不同的版本:My ...
- C# winfrom 模拟ftp文件管理
从网上找到的非常好用的模拟ftp管理代码,整理了一下,希望对需要的人有帮助 using System; using System.Collections.Generic; using System.T ...
- js执行环境深入研究
js 声明函数是创建函数对象的过程,当创建函数对象时,函数对象的[[scope]] =连当前执行环境对象的作用域(栈顶执行环境--当执行函数时,js会将该函数的执行环境对象入栈) 当为全局函数时,如: ...
- W3C-XML
XML XML Extensible Markup Language,可扩展标记语言 1 XML和HTML的区别 XML主要用来传输数据 HTML主要用来呈现数据内容 2 XML的主要用途 传输数据 ...
- 利用JQuery实现全选和反选的几种方法
前面介绍了利用JavaScript实现全选功能,其中也有要注意的几点,现在讲解下在JQuery怎么实现全选和反选,下面提供了两种方法实现. 如图:要实现的效果是点击全选框全部选中,再点击全部不选中 方 ...
- NSArray数组的学习总结
1.不可变数组NSArray NSArray是不可变的,而且只能储存Object-c对象.另外,数组的最后一个元素一定是nil,表示结束. 注:这些集合类只能收集cocoa对象(NSOjbect对象) ...
- linux网络编程:使用单进程实现多客户端通信
服务端: //回射服务器 //避免僵尸进程 #include "unistd.h" #include "sys/types.h" #include " ...
- js获取当期日期累加天数
本文是转载的,,忘记出处了,我用上了,也给大家分享一下 一.日期减去天数等于第二个日期 function cc(dd,dadd)...{//可以加上错误处理var a = new Date(dd)a ...