hdu 3887 Counting Offspring 树上求所有节点的子树上比当前节点小的个数 树状数组
2011-07-26 16:54
435 查看
[align=left]Problem Description[/align]
[align=left]Input[/align]
[align=left]Output[/align]
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=510000;
struct Node
{
int t;
int next;
};
int p[maxn];
Node G[maxn*2];
int l;
int ans[maxn];
int V,root;
void init()
{
memset(p,-1,sizeof(p));
memset(ans,0,sizeof(ans));
l=0;
}
void addedge(int u,int t,int l)
{
G[l].t=t;
G[l].next=p[u];
p[u]=l;
}
int c[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
int getsum(int x)
{
if(x==0) return 0;
int cnt=0;
for(int i=x;i>=1;i-=lowbit(i))
{
cnt+=c[i];
}
return cnt;
}
int vis[maxn];
int stc[maxn];
int before[maxn];
int stp;
void calc()
{
memset(vis,0,sizeof(vis));
stp=0;
stc[++stp]=root;
while(stp>0)
{
int u=stc[stp];
if(vis[u]==0)
{
vis[u]=1;
before[u]=getsum(u-1);
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].t;
if(vis[t]==0)
{
stc[++stp]=t;
}
}
continue;
}
int after=getsum(u-1);
ans[u]=after-before[u];
vis[u]=2;
stp--;
update(u,1);
}
}
int main()
{
while(scanf("%d%d",&V,&root)==2&&V)
{
init();n=V;
for(int i=0;i<V-1;i++)
{
int u,t;scanf("%d%d",&u,&t);
addedge(u,t,l++);
addedge(t,u,l++);
}
calc();
printf("%d",ans[1]);
for(int i=2;i<=V;i++) printf(" %d",ans[i]);printf("\n");
}
return 0;
}
You are given a tree, it’s root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose number is less than i in all the succeeding nodes of node i. Now we need to calculate f(i) for any possible i.
[align=left]Input[/align]
Multiple cases (no more than 10), for each case: The first line contains two integers n (0<n<=10^5) and p, representing this tree has n nodes, its root is p. Following n-1 lines, each line has two integers, representing an edge in this tree. The input terminates with two zeros.
[align=left]Output[/align]
For each test case, output n integer in one line representing f(1), f(2) … f(n), separated by a space.
[align=left]Sample Input[/align]
15 7 7 10 7 1 7 9 7 3 7 4 10 14 14 2 14 13 9 11 9 6 6 5 6 8 3 15 3 12 0 0
[align=left]Sample Output[/align]
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=510000;
struct Node
{
int t;
int next;
};
int p[maxn];
Node G[maxn*2];
int l;
int ans[maxn];
int V,root;
void init()
{
memset(p,-1,sizeof(p));
memset(ans,0,sizeof(ans));
l=0;
}
void addedge(int u,int t,int l)
{
G[l].t=t;
G[l].next=p[u];
p[u]=l;
}
int c[maxn];
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
int getsum(int x)
{
if(x==0) return 0;
int cnt=0;
for(int i=x;i>=1;i-=lowbit(i))
{
cnt+=c[i];
}
return cnt;
}
int vis[maxn];
int stc[maxn];
int before[maxn];
int stp;
void calc()
{
memset(vis,0,sizeof(vis));
stp=0;
stc[++stp]=root;
while(stp>0)
{
int u=stc[stp];
if(vis[u]==0)
{
vis[u]=1;
before[u]=getsum(u-1);
for(int i=p[u];i!=-1;i=G[i].next)
{
int t=G[i].t;
if(vis[t]==0)
{
stc[++stp]=t;
}
}
continue;
}
int after=getsum(u-1);
ans[u]=after-before[u];
vis[u]=2;
stp--;
update(u,1);
}
}
int main()
{
while(scanf("%d%d",&V,&root)==2&&V)
{
init();n=V;
for(int i=0;i<V-1;i++)
{
int u,t;scanf("%d%d",&u,&t);
addedge(u,t,l++);
addedge(t,u,l++);
}
calc();
printf("%d",ans[1]);
for(int i=2;i<=V;i++) printf(" %d",ans[i]);printf("\n");
}
return 0;
}
相关文章推荐
- hdu 3974 Assign the task 树上操作,更改每棵子树的值,查询各节点当前值 线段树+时间戳
- hdu 5678 ztr loves trees (给一颗有根树,树上的每一个节点有一个权值,每次询问某个子树中所有权值的中位数)
- hdu 4008 Parent and son 在树上查询以X为根的Y的儿子和子树节点中的最小节点 标记时间戳
- 根据当前节点获取所有上层结构的组织(递归算法)
- 对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。
- hdu 5692 (节点深度为h 所有子节点
- 两个节点在依存树上的最短子树(Java)
- hdu 5692 (节点深度为h 所有子节点
- 第4章第1节练习题12 删除以指定节点为根节点的所有子树
- HDU 4916(Count on the path-树上除链上的节点外最小值[强制在线])
- 对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。
- 今天开始学Java 现在有一棵合法的二叉树,树的节点都是用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度
- hdu 5692 (节点深度为h 所有子节点
- oracle 递归查询 查询当前选中节点的所有子节点
- HDU_2196_Computer(树上节点的最长路径 · dfs / bfs)
- activiti 工作流会签 / 多人审批时一人通过也可 / 在当前节点获取下一节点的信息 / 流程部署之后发布之前获取所有节点的信息 / 流程启动开始之前传送之后节点办理人 / 同一结点设置多个监听
- 给一个二叉树,每个节点都是正或负整数,如何找到一个子树,它所有节点的和最大?
- hdu 5692 (节点深度为h 所有子节点
- MySql 获取当前节点及递归所有上级节点
- 第4章第1节练习题7 交换二叉树所有节点左右子树