BZOJ2863: 愤怒的元首

来源:互联网 发布:java中string转byte 编辑:程序博客网 时间:2024/04/29 20:09

很明显这一题就是要求DAG组合数
问了tangjz 他直接甩给我一个公式…
不敢问证明感觉根据块的大小分一下可以搞出来?
有一个公式:
A[i]=ik=1(1)k1Cki2k(ik)A[ik]
其中A[0]=1
A[i]表示有i个节点时的答案 包括不连边的情况

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const   int Mod=1000000007;int fact[2000001],fact_[2000001];int Max=2000000;int S[9193991];int ff(int x,int yt){ if(x==2&&yt<=9000000)      if(S[yt])return S[yt];   int base=1,res=1,M=x,y=yt;    while(y)    {       if(y&base)           y^=base,res=res*1ll*M%Mod;        base<<=1;        M=M*1ll*M%Mod;    } if(x==2&&yt<=9000000)    return S[yt]=res;  return res;}int A[4001];char c;inline void read(int &a){  a=0;do c=getchar();while(c<'0'||c>'9');  while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}int main(){    int i,j,k;    int n,m;    read(n);     fact[1]=1;    fact[0]=fact[1]=fact_[1]=fact_[0]=1;    Max=n;    for(i=2;i<=Max;i++)    fact[i]=fact[i-1]*1ll*i%Mod;    fact_[Max]=ff(fact[Max],Mod-2);    for(int i=Max-1;i;i--)     fact_[i]=fact_[i+1]*(i+1ll)%Mod;    int ans=0;    A[0]=1;    for(int i=1;i<=n;i++)        for(int j=1;j<=i;j++)            A[i]+=((((j&1?1ll:-1ll)*fact[i]*fact_[i-j]%Mod)*fact_[j]%Mod)*A[i-j]%Mod)*ff(2,j*(i-j))%Mod,A[i]%=Mod;    printf("%d\n",(A[n]+Mod)%Mod);    return 0;}
0 0
原创粉丝点击