您的位置:首页 > 编程语言 > Java开发

hdu 3887 Counting Offspring 树上求所有节点的子树上比当前节点小的个数 树状数组

2011-07-26 16:54 435 查看
[align=left]Problem Description[/align]
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐