hdu 3887 Counting Offspring

题目大意:给你一棵树,求每个父节点的子树中序号小于父节点序号的节点个数。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;

const int N=100000+5;

int n,stk[N],st[N],ed[N],ans[N],c[N],vis[N];

vector<int>v[N];

int sum(int x)
{
    int ret=0;
    while(x>0)
    {
        ret+=c[x];
        x-=x&(-x);
    }
    return ret;
}

void add(int x)
{
    while(x<=n)
    {
        c[x]+=1;
        x+=x&(-x);
    }
}

void dfs(int s)
{
    int p,top=0;
    memset(c,0,sizeof(c));
    memset(vis,0,sizeof(vis));
    stk[top++]=s;
    while(top)
    {
        p=stk[top-1];
        if(!vis[p])
        {
            st[p]=sum(p);
            vis[p]=1;
        }

        if(v[p].size())
        {
            if(vis[v[p].back()]==0)
                {
                    stk[top++]=v[p].back();
                }
            v[p].pop_back();
        }
        else
        {
           ed[p]=sum(p);
           ans[p]=ed[p]-st[p];
           add(p);
           top--;
        }

    }
}

int main()
{
    int i,x,y,s;
    while(~scanf("%d%d",&n,&s)&&n)
    {
        for(i=1;i<=n;i++) v[i].clear();
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }

        dfs(s);
        for(i=1;i<n;i++)
            printf("%d ",ans[i]);

        printf("%d\n",ans[n]);
    }
    return 0;
}

你可能感兴趣的:(hdu 3887 Counting Offspring)