Bzoj3456 城市规划

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 681  Solved: 383

Description

 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通. 为了省钱, 每两个城市之间最多只能有一条直接的贸易路径. 对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.
 好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出n个点的简单(无重边无自环)无向连通图数目.
 由于这个数字可能非常大, 你只需要输出方案数mod 1004535809(479 * 2 ^ 21 + 1)即可.

Input

 仅一行一个整数n(<=130000)
 

Output

 仅一行一个整数, 为方案数 mod 1004535809.
 

Sample Input

3

Sample Output

4

HINT

 对于 100%的数据, n <= 130000

Source

 

POJ1737 Connected Graph 的升级版

在上面那道题中可以得到基本的递推公式 $ F[i]=2^C_{n}^{2} − \sum_{j=1}^{i-1} (C(i-1,j-1)*F[j]*2^C_{i-j}^{2} $

 

数学问题 动态规划 NTT 生成函数 多项式求逆

蒟蒻自带大常数,TLE简直无情

经过了一番艰苦卓绝的优化,可算是过了。

懒得贴公式了,留坑日后填

 

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstring>
  5 #define LL long long
  6 using namespace std;
  7 const LL mod=1004535809;
  8 const int G=3;
  9 const int mxn=1000007;
 10 int ansksm[mxn];
 11 int ksm(LL a,LL k){
 12     if(a==3 && k<mxn && ansksm[k])return ansksm[k];
 13     int tmp=k;
 14     LL res=1;a%=mod;
 15     while(k){
 16         if(k&1)res=(res*a)%mod;
 17         a=a*a%mod;
 18         k>>=1;
 19     }
 20     if(a==3)ansksm[tmp]=res;
 21     return res;
 22 }
 23 LL fac[mxn],inv[mxn];
 24 void init(int mxn){
 25     fac[0]=fac[1]=1;
 26     inv[0]=inv[1]=1;
 27     for(int i=2;i<mxn;i++){
 28         fac[i]=i*fac[i-1]%mod;
 29         inv[i]=((-mod/i*inv[mod%i])%mod+mod)%mod;
 30     }
 31     for(int i=2;i<mxn;i++)inv[i]=inv[i]*inv[i-1]%mod;
 32     return;
 33 }
 34 //
 35 int wn[mxn],wr[mxn];
 36 int N,len,rev[mxn];
 37 void NTT(LL *a,int flag){
 38     int i,j,k;
 39     for(i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
 40     for(i=1;i<N;i<<=1){
 41         int p=i<<1;
 42 //        LL gn=ksm(G,(flag==1)?(mod-1)/p:(mod-1)-(mod-1)/p);
 43         int gn;gn=(flag==1)?wn[i]:gn=wr[i];
 44         for(j=0;j<N;j+=p){
 45             LL g=1;
 46             for(k=0;k<i;k++,g=g*gn%mod){
 47                 int x=a[j+k],y=g*a[j+k+i]%mod;
 48                 a[j+k]=x+y;if(a[j+k]>mod)a[j+k]-=mod;
 49                 a[j+k+i]=x-y;if(a[j+k+i]<0)a[j+k+i]+=mod;
 50             }
 51         }
 52     }
 53     if(flag==-1){
 54         LL INV=ksm(N,mod-2);
 55         for(i=0;i<N;i++)a[i]=a[i]*INV%mod;
 56     }
 57     return;
 58 }
 59 //
 60 LL a[mxn],b[mxn],c[mxn];
 61 void Get_inv(int n,LL *a){
 62     if(n==1){b[0]=1;return;}
 63     Get_inv((n+1)>>1,a);
 64 //    printf("Get %d\n",n);
 65     int m=n,i;
 66     for(N=1,len=0;N<=m;N<<=1)len++;
 67     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
 68     for(i=0;i<n;i++)c[i]=a[i];    
 69     for(register int i=n;i<N;i++)c[i]=0;
 70     NTT(c,1);NTT(b,1);
 71     for(i=0;i<N;i++){
 72         b[i]=(2-(LL)c[i]*b[i]%mod)*b[i]%mod;
 73         if(b[i]<0)b[i]+=mod;
 74     }
 75     NTT(b,-1);
 76     for(i=n;i<N;i++)b[i]=0;
 77     return;
 78 }
 79 int n;
 80 int main(){
 81 //    freopen("in.txt","r",stdin);
 82     int i,j;
 83     scanf("%d",&n);
 84     int ed=n*2;
 85     init(ed+1);
 86     for (int i=1;i<=ed;i<<=1){
 87         wn[i]=ksm(3,(mod-1)/(i<<1));
 88         wr[i]=ksm(3,(mod-1)-(mod-1)/(i<<1));
 89     }
 90     int m=n;
 91     for(N=1,len=0;N<=m;N<<=1)len++;
 92     a[0]=1;
 93     for(i=1;i<=n;i++)a[i]=ksm(2,((LL)i*(i-1)/2)%(mod-1))*inv[i]%mod;
 94     Get_inv(N,a);
 95     for(N=1,len=0;N<=m;N<<=1)len++;
 96     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
 97     for(i=1;i<=n;i++)c[i]=ksm(2,(LL)i*(i-1)/2%(mod-1))*inv[i-1]%mod;
 98     c[0]=0;for(i=n+1;i<N;i++)c[i]=0;
 99     NTT(b,1);NTT(c,1);
100     for(i=0;i<N;i++)b[i]=b[i]*c[i]%mod;
101     NTT(b,-1);
102     printf("%lld\n",b[n]*fac[n-1]%mod);
103     return 0;
104 }

 

posted @ 2017-05-01 23:03  SilverNebula  阅读(234)  评论(0编辑  收藏  举报
AmazingCounters.com