hdu 3887 Counting Offspring
来源:互联网 发布:手机淘宝怎么快速秒杀 编辑:程序博客网 时间:2024/05/20 13:39
http://acm.hdu.edu.cn/showproblem.php?pid=3887
Counting Offspring
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 348 Accepted Submission(s): 111
Problem Description
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.
Input
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.
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.
Output
For each test case, output n integer in one line representing f(1), f(2) … f(n), separated by a space.
Sample Input
15 77 107 17 97 37 410 1414 214 139 119 66 56 83 153 120 0
Sample Output
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
题意:给定一棵树,已知根节点,求f [ i ],f [ i ]为以 i 为根节点的子树的比 i 小的节点个数。
分析:后序遍历树,就可以得到以每个节点为根的子节点所在的区间,如:样例后续遍历得到的区间为:
后序遍历序列:2 13 14 10 1 11 5 8 6 9 12 15 3 4 7
时间戳: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
以9为根节点的子节点就会在一段连续的区间内(下划线部分),用[s [ i ] , t [ i ]]记录以i为根的子节点所在的区间,如9的子节点的区间为[6,10],现在的问题就是求区间[6,10]内比9小的节点的个数,自然想到树状数组。用[1,10]内比9小的个数减去[1,5]内比9小的个数就是答案。所以从做到右扫描时间戳,对于时间i,对于所有的k满足s[k]=i的节点k查询当前比k小的个数,保存在ans1[k]中,并更新树状数组。第二次扫描,对于时间i,对于所有的k满足t[k]=i的节点查询比k小的个数,保存在ans2[k]中,并更新树状数组。最后对于所有的k,f[k]=ans2[k]-ans1[k]。
ps:后序遍历栈模拟,递归容易暴栈
#include<stdio.h>#include<string.h>#define N 100050int t;int n,a[N],b[N],c[N],num[N];int e,head[N],nxt[N+N],pnt[N+N];char vis[N];int ans1[N],ans[N],r[N];void addedge(int u,int v){pnt[e]=v;nxt[e]=head[u];head[u]=e++;pnt[e]=u;nxt[e]=head[v];head[v]=e++;}int s[N],top=0;void dfs(int u) //先序遍历,后序遍历得到的序列就是把先序遍历序列反过来{ //a[u]就是上面所说的t[u],b[u]就是上面所说的s[u]int v,i;s[top++]=u;vis[u]=1;a[u]=t;while(top>0){u=s[top-1];num[u]++;for(i=head[u];i!=-1;i=nxt[i]){v=pnt[i];head[u]=nxt[i];if(vis[v]==0){s[top++]=v;vis[v]=1;t--;a[v]=t;break;}}if(i==-1){top--;b[u]=t;}}}int lowbit(int x){return x&(-x);}void update(int i,int val){while(i<=n){c[i]+=val;i+=lowbit(i);}}int query(int i){int sum=0;while(i>0){sum+=c[i];i-=lowbit(i);}return sum;}int e1,pnt1[N],nxt1[N],head1[N];void addedge1(int u,int v){pnt1[e1]=v;nxt1[e1]=head1[u];head1[u]=e1++;}int main(){int root,i,j,u,v;while(scanf("%d%d",&n,&root)!=EOF){if(n==0&&root==0)break;t=n;e=0;memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));memset(num,0,sizeof(num));for(i=1;i<n;i++){scanf("%d%d",&u,&v);addedge(u,v);}dfs(root);e1=0;memset(head1,-1,sizeof(head1));for(i=1;i<=n;i++){r[a[i]]=i;addedge1(b[i],i); //链表插入s[k]=i的所有k}memset(c,0,sizeof(c));for(i=1;i<=n;i++){for(j=head1[i];j!=-1;j=nxt1[j]){v=pnt1[j];ans1[v]=query(v);}update(r[i],1);}memset(c,0,sizeof(c));for(i=1;i<=n;i++){ans[r[i]]=query(r[i])-ans1[r[i]];update(r[i],1);}printf("%d",ans[1]);for(i=2;i<=n;i++)printf(" %d",ans[i]);printf("\n");}return 0;}
- hdu 3887 Counting Offspring
- HDU 3887 Counting Offspring
- hdu 3887 Counting Offspring
- HDU 3887 Counting Offspring 树状数组
- HDU 3887 Counting Offspring (树状数组)
- HDU 3887 Counting Offspring 树状数组 + 栈模拟dfs
- HDU 3887 Counting Offspring dfs序的运用 | 非递归
- HDU 3887 Counting Offspring(dfs序的应用)
- HDU 3887 Counting Offspring (DFS + BIT或划分树)
- HDU ACM 3887 Counting Offspring 树状数组+DFS
- HDU 3887 Counting Offspring(dfs序 + 树状数组)
- HDU-3887-Counting Offspring-dfs序+树状数组
- hdu 3887 Counting Offspring dfs 树 树状数组
- HDU 3887 Counting Offspring(dfs序+树状数组)
- HDU 3887 Counting Offspring (树状数组+dfs)
- hdu 3887 Counting Offspring(dfs序+树状数组)
- 杭电 3887 Counting Offspring
- HDU--3887[Counting Offspring] DFS标号+线段树O(N*logN)
- 一笺梦
- bbs
- php 获取随机数
- Python语言中的按位运算
- JAVA [ HTTP ]
- hdu 3887 Counting Offspring
- 指针例子
- 网络编程初步认识(一)
- iphone开发-SQLite数据库使用
- C++中的static关键字
- java验证身份证
- JAVA [ 多线程 ]
- 1.java基础语法易忘点
- MapReduce技术的初步了解与学习