zoukankan      html  css  js  c++  java
  • 雅礼集训DAY 6 T1 xmasdag

        感谢gryz的mly大好人再次给我提供了题目和数据。

        和昨晚那个题几乎一样,都是x^n最后转化成第二类斯特林数*阶乘*Σ(和路径长度有关的组合数),而因为组合数是可以利用Pascal公式实现O(1)递推的,所以最后的复杂度都降为O(NK)。

        随便推一下,

    ANS(x)=Σ(p是1到x的一条路径) len(p)^k = Σ(h=1 to k) S(k,h) Σ(p是1到x的一条路径)P(len(p),h)= Σ(h=1 to k) S(k,h)*h!*Σ(p是1到x的一条路径)C(len(p),h)。

        所以我们设now[x][i]=Σ(p是1到x的一条路径)C(len(p),i)。

        因为保证了是个DAG且1可以到达所有节点,所以图中只有1的入度是0,然后我们直接从1开始拓扑排序就行了。

    需要注意的是因为这个题只是求1到x的路径,所以除了now[1][0],其他的now[x][0]一开始都是0,而不像昨天的那个题是求树上任意一个其他点到它的路径。

         (总感觉我脸黑常熟大的样子,如图)

    code:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define maxn 100005
    #define ha 998244353
    #define pb push_back
    using namespace std;
    vector<int> g[maxn]; 
    int ans,n,k,m,id[maxn];
    int S[505][505],jc[505];
    int q[maxn],hd=1,tl=0;
    int now[maxn][505];
    
    inline void init(){
        S[0][0]=1,jc[0]=1;
        for(int i=1;i<=500;i++){
            jc[i]=jc[i-1]*(ll)i%ha;
            for(int j=1;j<=500;j++) S[i][j]=((ll)S[i-1][j-1]+S[i-1][j]*(ll)j)%ha;
        }
    }
    
    inline void solve(){
        q[++tl]=1,now[1][0]=1;
        int x,to;
        while(hd<=tl){
            x=q[hd++];
            for(int i=g[x].size()-1;i>=0;i--){
                to=g[x][i];
                now[to][0]+=now[x][0];
                if(now[to][0]>=ha) now[to][0]-=ha;
                for(int j=1;j<=k;j++){
                    now[to][j]+=now[x][j];
                    if(now[to][j]>=ha) now[to][j]-=ha;
                    now[to][j]+=now[x][j-1];
                    if(now[to][j]>=ha) now[to][j]-=ha;
                }
                
                if(!(--id[to])) q[++tl]=to;
            }
        }
    }
    
    int main(){
        freopen("xmasdag.in","r",stdin);
        freopen("xmasdag.out","w",stdout);
        
        init();
        
        scanf("%d%d%d",&n,&m,&k);
        int uu,vv;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&uu,&vv);
            g[uu].pb(vv),id[vv]++;
        }
        
    //    for(int i=1;i<=n;i++) now[i][0]=1;
        solve();
        
        for(int i=1;i<=n;i++){
            ans=0;
            for(int j=1;j<=k;j++) ans=((ll)ans+S[k][j]*(ll)jc[j]%ha*(ll)now[i][j])%ha;
            printf("%d
    ",ans);
        }
        
        return 0;
    }

     

    我爱学习,学习使我快乐
  • 相关阅读:
    Button
    启动活动最佳写法
    随时随地退出程序
    知晓当前是在哪个活动
    Failed to resolve:com.android.support:appcompat-v7:报错处理
    未能从程序集“System.ServiceModel”中加载类型“System.ServiceModel.Activation.HttpModule”
    office文档图标不正常显示
    feign和ribbon的异常捕捉
    rocketMQ为什么会重复消费
    springboot时区问题
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8227431.html
Copyright © 2011-2022 走看看