dfs序理解-hdu3887
dfs序就是相当于把树转化成了一个区间,在区间上进行操作。
void dfs(int u, int fa) {
l[u]=++key;
for (int i=head[u]; i!=-; i=e[i].next) {
int v=e[i].v;
if (v!=fa) {
dfs(v, u);
}
}
r[u]=key;
}
hdu3887
题意:问你1-n这些节点的子节点下面有多少个比他小的节点。
其实仔细看跟树状数组的逆序数很像啊,算是dfs序的入门题了
从1-n分别对他们的所属的区间[l-1, r]进行操作,对l进行+1的操作。
因为对小的那个操作就相当于树状数组的逆序数的操作,就可以求出多少个比节点小的了。
/* gyt
Live up to every day */
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = ;
const ll maxm = 1e7;
const ll base = ;
const int INF = <<;
const db eps = 1e-;
const ll mod = 1e9+;
int l[maxn], r[maxn];
int key, cnt;
struct edge{
int u, v, next;
}e[maxn*];
int head[maxn];
int c[maxn];
int ans[maxn]; void init() {
key=; cnt=;
memset(c, , sizeof(c));
memset(l, , sizeof(l));
memset(r, , sizeof(r));
memset(ans, , sizeof(ans));
memset(head, -, sizeof(head));
}
void dfs(int u, int fa) {
l[u]=++key;
for (int i=head[u]; i!=-; i=e[i].next) {
int v=e[i].v;
if (v!=fa) {
dfs(v, u);
}
}
r[u]=key;
}
void add(int u, int v) {
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
int lowbit(int x) {
return x&-x;
}
void updata(int x, int d) {
while(x<maxn) {
c[x]+=d;
x+=lowbit(x);
}
}
int getsum(int x) {
int ret=;
while(x>) {
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void solve() {
int n, root;
while(scanf("%d%d", &n, &root)!=EOF) {
if (!n&&!root) break;
init();
for (int i=; i<n-; i++) {
int u, v; scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(root, -);
for (int i=; i<=n; i++) {
//cout<<r[i]<<" "<<l[i]<<endl;
ans[i]=getsum(r[i])-getsum(l[i]-);
//cout<<getsum(r[i])<<" " << getsum(l[i]-1)<<endl;
updata(l[i], );
}
for (int i=; i<=n; i++) {
if(i!=) printf(" ");
printf("%d", ans[i]);
}
puts("");
}
}
int main() {
int t = ;
//freopen("in.txt","r",stdin);
// freopen("gcd.out","w",stdout);
//scanf("%d", &t);
while(t--)
solve();
return ;
}
dfs序理解-hdu3887的更多相关文章
- POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)
http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...
- [poj3321]Apple Tree(dfs序+树状数组)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26762 Accepted: 7947 Descr ...
- dfs序和欧拉序
生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解. 一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...
- BZOJ2434[Noi2011]阿狸的打字机——AC自动机+dfs序+树状数组
题目描述 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小 ...
- 图论:DFS序
DFS序可以把树转到区间上再用高级数据结构维护,比树链剖分好理解很多 一个闭区间就是一棵子树 POJ3321 #include<cstdio> ; ; int n,m,id,cnt; in ...
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
- 【AC自动机】【树状数组】【dfs序】洛谷 P2414 [NOI2011]阿狸的打字机 题解
这一题是对AC自动机的充分理解和树dfs序的巧妙运用. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和' ...
- bzoj3786 星际探索 splay dfs序
这道题 首先 因为他求的是当前点到根节点的路径和 我们可以将题目转换为括号序列的写法 将点拆为左括号以及右括号 左括号为正 右括号为负 这样题目就变为了求前缀和了 如果一个点是这个点的子树 那么他的左 ...
- 树的dfs序 && 系统栈 && c++ rope
利用树的dfs序解决问题: 就是dfs的时候记录每个节点的进入时间和离开时间,这样一个完整的区间就是一颗完整的树,就转化成了区间维护的问题. 比如hdu3887 本质上是一个求子树和的问题 #incl ...
随机推荐
- Zabbix配置优化
1.zabbix开启中文语言zabbix是一个多语言监控系统,默认使用英文并且也支持中文语言,详见<zabbix汉化方法>,但是安装zabbix里面看不到中文语言.请往下看: 
ASP.NET MVC 中有个标签:@Html.AntiForgeryToken(),需要在页面中加入这个标签,然后在Actoin中加入特性[ValidateAntiForgeryToken]就可以了 ...
- bootstrap日历控件
bootstrap的日历控件: <link href="~/bootstrap/css/bootstrap.min.css" rel="stylesheet&quo ...