zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 160 F

    题:https://atcoder.jp/contests/abc160/tasks/abc160_f

    题意:给定一棵树,问以每个节点为开始的拓扑排序有多少个;

    分析:全部的情况为n!,那么得在其中挑选出合法的,因为要求拓扑排序,所以要求根要为第一个节点,所以是从sz[u]选出1个方案,即乘上C(sz[u],1),对于递归下去的每个节点也时这种情况。所以真正要维护的就是size的前缀积既可。

    #include<bits/stdc++.h>
    using namespace std;
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    #define pb push_back
    typedef long long ll;
    const int M=1e6+6;
    const int mod=1e9+7;
    vector<int>g[M];
    ll facn=1;
    int n;
    ll ans[M],sz[M],mul[M],fac[M];
    ll ksm(ll a,ll b){
        a%=mod;
        ll t=1;
        while(b){
            if(b&1)
                t=t*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return t;
    }
    void dfs1(int u,int fa){
        sz[u]=mul[u]=1;
        for(auto v:g[u]){
            if(v!=fa){
                dfs1(v,u);
                sz[u]+=sz[v];
                mul[u]=mul[u]*mul[v]%mod;
            }
        }
        mul[u]=mul[u]*sz[u]%mod;
    }
    void dfs2(int u,int fa,ll last){
        ll tmp=last;
        for(auto v:g[u])
            if(v!=fa)
                tmp*=mul[v],tmp%=mod;
        ans[u]=facn*ksm(tmp,mod-2)%mod;
        for(auto v:g[u])
            if(v!=fa)
                last*=mul[v],last%=mod;
        for(auto v:g[u])
            if(v!=fa)
                dfs2(v,u,last*ksm(mul[v],mod-2)%mod*(n-sz[v])%mod);
    }
    int main(){
        scanf("%d",&n);
        for(ll i=2;i<n;i++)
            facn*=i,facn%=mod;
        for(int u,v,i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            g[u].pb(v);
            g[v].pb(u);
        }
        dfs1(1,0);
        dfs2(1,0,1);
        for(int i=1;i<=n;i++)
            printf("%lld
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    课后作业之找水王
    SCRUM第二阶段第十天
    第九周总结
    冲刺一3
    用户项目
    预会热词统计
    冲刺一2
    冲刺一(一阶)1
    第八周总结
    小组合作
  • 原文地址:https://www.cnblogs.com/starve/p/12626868.html
Copyright © 2011-2022 走看看