zoukankan      html  css  js  c++  java
  • 「NOIP2021模拟赛8.26 A」赝作家 题解

    题目大意

    • 有一张 (n) 个点 (m) 条边的有向无环图,没有重边,且从1号点出发能够到达所有点。

    • 已知 ({1,2,3,...,n}) 是这张图的一种拓扑序列,求有多少种可能的图。

    问题求解

    我们发现这个问题可以分成三类

    1. 对于 (m<n-1) 显然是 (0)

    2. 对于 (m=n-1) 可以分析,第 (i) 个点,可以连到前 (i-1) 个点任意一个上都是一种不同的方案,所以答案就是 ((n-1)!)

    3. 对于 (m=n) 的问题我们拿来分类讨论,设 (f(i)) 表示 (m) 条边 (n) 个点的方案数

    • 如果第 (i) 个点连了两条边,剩下 (i-1) 个点连 (i-2) 条边,也就是 ((i-2)!) ,边要连到任意两个点上,也就是 (C_{i-1}^2)

    • 如果第 (i) 个点连了一条边,显然方案数就是 (f(i-1) imes i)

    所以 (f(i)=(i-2)! imes C_{i-1}^2 +f(i-1) imes i)

    代码实现

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=1e6+5;
    const LL TT=998244353;
    LL Fct[maxn],F[maxn],N,M;
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    int main(){
    	N=read();M=read();Fct[0]=1;
    	for(int i=1;i<=M;i++) Fct[i]=Fct[i-1]*i%TT;
    	if(M==N-1){printf("%lld
    ",Fct[M]);}
    	else if(M==N){for(LL i=1;i<N;i++)F[i]=(F[i-1]*i%TT+i*(i-1)/2%TT*Fct[i-1]%TT)%TT;printf("%lld
    ",F[N-1]);}
    	else printf("%d
    ",0);
    	return 0;
    }
    
  • 相关阅读:
    Scripts.Render 索引超出了数组界限
    AutoFac使用方法总结
    MFC中打开一个获取路径的对话框
    MFC中自定义消息
    获得窗口句柄的方法
    App Doc View Frame中指针的获取
    MFC中菜单的命令响应顺序
    机械设计软件编写心得
    对SVD奇异值分解的理解
    安装win8+Ubuntu14.04双系统的经验总结
  • 原文地址:https://www.cnblogs.com/martian148/p/15191087.html
Copyright © 2011-2022 走看看