• COGS 2039. 树的统计


    ★★   输入文件:counttree.in   输出文件:counttree.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【题目描述】

    关于树的统计问题有多种多样的版本,这里你需要解决一个比较简单的问题:对于一棵包含N个节点的有根树,将所有点从1到N编号后,对于每一个节点v,统计出以v为根的子树中有多少个点的编号比v小。

    【输入格式】

    输入第一行包含一个整数N,以下N行每行包含一个整数,其中第i行的整数表示编号为i的节点的父亲节点的编号,根的父亲节点编号为0。

    【输出格式】

    输出包含N行,其中第i行给出编号为i的节点的统计结果。

    【样例输入】

    3
    2
    3
    0
    

    【样例输出】

    0 1 2
    

    【提示】

    在此键入。

    【来源】

    20%的数据1<=n<=1000

    100%的数据1<=n<=100000

    树状数组

    屠龙宝刀点击就送

    #include <cstdio>
    #define N 100005
    
    struct Edge
    {
        int next,to;
    }edge[N];
    int ans[N],root,tag[N],n,fa[N],head[N],cnt;
    inline int lowbit(int x) {return x&(-x);}
    inline int query(int x)
    {
        int ans=0;
        for(;x;x-=lowbit(x)) ans+=tag[x];
        return ans;
    }
    inline void modify(int x)
    {
        for(;x<=n;x+=lowbit(x)) tag[x]++;
    }
    void dfs(int x)
    {
        ans[x]=-query(x-1);
        modify(x);
        for(int i=head[x];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(v!=fa[x])
            dfs(v);
        }
        ans[x]+=query(x-1);
    }
    int main()
    {
        freopen("counttree.in","r",stdin);freopen("counttree.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&fa[i]);
            if(!fa[i]) root=i;
            else
            {
                edge[++cnt].next=head[fa[i]];
                edge[cnt].to=i;
                head[fa[i]]=cnt;
            }
        }
        dfs(root);
        for(int i=1;i<=n;++i) printf("%d ",ans[i]);
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    Linux各目录的意义
    LinuxVIM编辑器用法
    Linux自动同步时间
    bash的基本特性
    shell-homeworkone
    shell
    笔记
    Python-1-Day
    Linux使用BIND提供域名解析服务
    Linuxautofs自动挂载服务
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7413764.html
Copyright © 2020-2023  润新知