• [BZOJ2863]愤怒的元首


    Description
    Pty生活在一个奇葩的国家,这个国家有n个城市,编号为1~n。
    每个城市到达其他城市的路径都是有向的。
    不存在两个城市可以互相到达。
    这个国家的元首现在很愤怒,他大喊一声“气死偶咧!”,然后决定把所有的路径都毁掉再重建。
    元首想知道有多少种重建的方案使得这个国家仍然奇葩。

    Input
    第一行一个整数:n

    Output
    输出n个城市的重建方案数mod(10^9+7)的结果
    Hint:基图不连通也是合法方案

    Sample Input
    3

    Sample Output
    25

    HINT
    n <= 3000


    (f[i])表示当前(i)个点构成的DAG数量,删掉出度为零的点后图依然是个DAG,因此我们可以枚举出度为零的点的个数,得到(f[i]=sum_{j=1}^{i}{f[i-j]*2^{j*(i-j)}*C(i,j)})

    但是我们这样枚举出来的是至少有(j)个出度为零的点,因此我们使用广义容斥定理乘上容斥系数,最终答案为(f[i]=sum_{j=1}^{i}{(-1)^{j}f[i-j]*2^{j*(i-j)}*C(i,j)})

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=3e3,p=1e9+7;
    int c[N+10][N+10],f[N+10];
    int mlt(int a,int b){
    	int res=1;
    	for (;b;b>>=1,a=1ll*a*a%p)	if (b&1)	res=1ll*res*a%p;
    	return res;
    }
    int main(){
    	int n=read();
    	c[0][0]=1;
    	for (int i=1;i<=n;i++){
    		c[i][0]=1;
    		for (int j=1;j<=i;j++)	c[i][j]=(c[i-1][j]+c[i-1][j-1])%p;
    	}
    	f[0]=1;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=i;j++)
    			f[i]=(f[i]+1ll*(j&1?1:-1)*c[i][j]*mlt(2,j*(i-j))%p*f[i-j]%p)%p;
    	printf("%d
    ",(f[n]+p)%p);
    	return 0;
    }
    
  • 相关阅读:
    Editor HDU
    Out of Sorts II
    庭师的利刃
    HDU 2087: 剪花布条
    【高精度】高精度乘法
    【高精度】高精度数除以低精度数I
    【高精度】高精度阶乘
    【高精度】高精度分数
    【高精度】简单高精度减法
    【高精度】简单高精度加法
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10021085.html
Copyright © 2020-2023  润新知