hdu某道题
来源:互联网 发布:微信公众号开发 php 编辑:程序博客网 时间:2024/05/16 08:30
题目大意:给出一棵树,求以i为根节点的子树中有多少个节点标号比i小
得到dfs序之后,用树状数组求第i个数之前比第i个数小的数的个数
ans[i]=ed[i]-st[i];
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;#define MAXN 100010int l,tot,n,p,x,y;struct point{ int y; int next;}edge[MAXN*2];typedef int arr[MAXN*4];arr st,ed,c,head,ans;void add(int x,int y){ l++; edge[l].y=y; edge[l].next=head[x]; head[x]=l;}void dfs(int x){ tot++; st[x]=tot; int p=head[x];//一定要定义成局部变量 while (p) { if (st[edge[p].y]==0) { dfs(edge[p].y); tot++; } p=edge[p].next; } if (st[x]==tot) tot++; ed[x]=tot;}int lowbit(int x){ return (x & (-x));}void updata(int x,int y){ while (x<=tot) { c[x]+=y; x+=lowbit(x); }}int sum(int x){ int tmp=0; while (x) { tmp+=c[x]; x-=lowbit(x); } return tmp;}int main(){ cin>>n>>p; while (n!=0 && p!=0) { l=0; memset(head,0,sizeof(head)); for (int i = 1;i < n;i++) { cin>>x>>y; add(x,y); add(y,x); } tot=0; memset(st,0,sizeof(st)); memset(ed,0,sizeof(ed)); dfs(p); memset(c,0,sizeof(c)); for (int i = 1;i <= n;i++) { ans[i]=sum(ed[i])-sum(st[i]); updata(st[i],1);//只记开始的即可 } for (int i = 1;i <= n;i++) cout<<ans[i]<<' '; cout<<endl; cin>>n>>p; } return 0;}
非递归:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;#define MAXN 100010int l,tot,n,p,x,y;struct point{ int y; int next;}edge[MAXN*2];typedef int arr[MAXN*4];arr st,ed,c,head,ans,sta;bool vis[100010];void add(int x,int y){ l++; edge[l].y=y; edge[l].next=head[x]; head[x]=l;}void dfs(int x){ int now=1; int tmp; vis[x]=1; sta[now]=x; while (now) { tmp=sta[now]; tot++; if (st[tmp]==0) st[tmp]=tot; int flag=0; p=head[tmp]; while (p) { if (vis[edge[p].y]==0) { now++; vis[edge[p].y]=1; sta[now]=edge[p].y; flag=1; break;//!! } p=edge[p].next; } if (flag==0) { if (st[tmp]==tot) tot++; ed[tmp]=tot; now--; } }}int lowbit(int x){ return (x & (-x));}void updata(int x,int y){ while (x<=tot) { c[x]+=y; x+=lowbit(x); }}int sum(int x){ int tmp=0; while (x) { tmp+=c[x]; x-=lowbit(x); } return tmp;}int main(){ cin>>n>>p; while (n!=0 && p!=0) { l=0; memset(head,0,sizeof(head)); for (int i = 1;i < n;i++) { cin>>x>>y; add(x,y); add(y,x); } tot=0; memset(st,0,sizeof(st)); memset(ed,0,sizeof(ed)); memset(vis,0,sizeof(vis)); dfs(p); memset(c,0,sizeof(c)); for (int i = 1;i <= n;i++) { ans[i]=sum(ed[i])-sum(st[i]); updata(st[i],1);//只记开始的即可 } for (int i = 1;i < n;i++) cout<<ans[i]<<' '; cout<<ans[n]<<endl; cin>>n>>p; } return 0;}
0 0
- hdu某道题
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- (一一三)使用系统自带框架操作SQLite3数据库
- iOS学习 - Objective-c之property
- 为什么要使用linux
- 每日20行之2~~~多线程创始 继承Thread还是实现Runnable 二者之间的区别
- MVC入门学习路由选择(一)
- hdu某道题
- js函数初级
- UVA_301_Transportation
- 分治法求 两个数组 X 和 Y 的中位数
- PHP生成静态文件
- 贪心算法之Radar Installation
- HDU 4287 Intelligent IME(哈希)
- KVC与KVO理解
- CNF范式生成器 CNFgen 安装教程