HDU ACM 3887 Counting Offspring 树状数组+DFS

来源:互联网 发布:linux boot 文件详解 编辑:程序博客网 时间:2024/05/09 09:29

分析:一棵树,求每个结点的子树中有几个数是小于这个数的。
dfs会进入一个节点一次,出一个节点一次,中间经过的点都是它的子树中的点,因此,进入的时候统计一遍,出来的时候统计一遍,两个结果相减即可,使用树状数组。
纯dfs会爆栈,需要重设栈的大小。

#pragma comment(linker,"/STACK:100000000,100000000")#include<iostream>#include<vector>using namespace std;#define N 100010int c[N];int ans[N];vector<int> map[N];int lowbit(int x){return x&(-x);}void update(int x,int d){while(x<N){c[x]+=d;x+=lowbit(x);}}int sum(int x){int an=0;while(x>0){an+=c[x];x-=lowbit(x);}return an;}void DFS(int x,int fa){int tmp,i;tmp=sum(x-1);for(i=0;i<map[x].size();i++)if(map[x][i]!=fa){update(map[x][i],1);DFS(map[x][i],x);}ans[x]=sum(x-1)-tmp;}int main()      {int n,root,i,a,b;ios::sync_with_stdio(false);while(cin>>n>>root && n+root){memset(c,0,sizeof(c));for(i=0;i<=n;i++)map[i].clear();for(i=0;i<n-1;i++){cin>>a>>b;map[a].push_back(b);map[b].push_back(a);}DFS(root,-1);for(i=1;i<n;i++)cout<<ans[i]<<" ";cout<<ans[i]<<endl;}    return 0;      }


0 0
原创粉丝点击