题目大意:给出一棵树,求以i为根节点的子树中有多少个节点标号比i小
得到dfs序之后,用树状数组求第i个数之前比第i个数小的数的个数
ans[i]=ed[i]-st[i];
#include
#include
#include
#include
using namespace std;
#define MAXN 100010
int 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<' ';
cout<cin>>n>>p;
}
return 0;
}
非递归:
#include
#include
#include
#include
using namespace std;
#define MAXN 100010
int 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<' ';
cout<cin>>n>>p;
}
return 0;
}