zoukankan      html  css  js  c++  java
  • [USACO17JAN] Promotion Counting晋升者计数 (树状数组+dfs)

    题目大意:给你一棵树,求以某节点为根的子树中,权值大于该节点权值的节点数

    本题考查dfs的性质

    离散+树状数组求逆序对

    先离散

    我们发现,求逆序对时,某节点的兄弟节点会干扰答案

    所以,我们在递推时统计一次答案,递归时再统计一次答案,两者的差值就是最终结果

    #include <bits/stdc++.h>
    #define dd double
    #define N 100100
    using namespace std;
    
    int n,cnt,ma,lst;
    int a[N],head[N],s[N],ans[N];
    struct EDGE{
        int to,nxt;
    }edge[N*2];
    struct node{
        int og,mx,id;
    }d[N];
    int cmp1(node a,node b) {return a.og<b.og;}
    int cmp2(node a,node b) {return a.id<b.id;}
    void update(int x,int p)
    {
        for(int i=x;i<=ma;i+=(i&(-i)))
        {
            s[i] += p; 
        }
    }
    int query(int x)
    {
        int ans=0;
        for(int i=x;i>0;i-=(i&(-i)))
        {
            ans += s[i];
        }
        return ans;
    }
    void edge_add(int u,int v)
    {
        cnt++;
        edge[cnt].to = v;
        edge[cnt].nxt= head[u];
        head[u] = cnt;
    }
    void discrete()
    {
        sort(d+1,d+n+1,cmp1);
        for(int i=1;i<=n;i++)
        {
            if(d[i].og==d[i-1].og)
            {
                d[i].mx=d[i-1].mx;
            }else{
                d[i].mx=++ma;
            }
        }
        sort(d+1,d+n+1,cmp2);
        for(int i=1;i<=n;i++) a[i] = d[i].mx;
    }
    void dfs(int x,int fa)
    {
        for(int j=head[x];j!=-1;j=edge[j].nxt)
        {
            int v=edge[j].to;
            if(v==fa) continue;
            int s1=query(ma)-query(a[x]);
            dfs(v,x);
            int s2=query(ma)-query(a[x]);
            ans[x] += s2-s1;
        }
        update(a[x],1);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {scanf("%d",&d[i].og);d[i].id=i;}
        memset(head,-1,sizeof(head));
        int x;
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&x);
            edge_add(i,x);
            edge_add(x,i);
        }
        discrete();
        dfs(1,-1);
        for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
        return 0;
    }
  • 相关阅读:
    Luogu P2495 [SDOI2011]消耗战
    40. Combination Sum II
    39. Combination Sum
    22. Generate Parentheses
    51. N-Queens
    Codeforces Round #346 (Div. 2) E. New Reform
    Codeforces Round #346 (Div. 2) D. Bicycle Race
    HDU 5651xiaoxin juju needs help
    VK Cup 2016
    Educational Codeforces Round 10 D. Nested Segments
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9678835.html
Copyright © 2011-2022 走看看