n<=1.3e5的无向简单连通图个数。mod 1004535809。
听说是很多人的多年坑。。?还好我见识少
首先用容斥递推,$f(i)$表示$i$个点答案。如果不考虑连通就是$2^{frac{i(i-1)}{2}}$,然后枚举所有不连通的情况(我就不会了)。
枚举最后一个点所在集合大小$j$,我需要在剩下$i-1$个点里面挑$j-1$个来陪他,然后这坨点联通的方案就$f(j)$,其他点乱连,就$2^{frac{(i-j)(i-j-1)}{2}}$。
好!$f(i)=2^{frac{i(i-1)}{2}}-sum_{j=1}^{i-1}C_{i-1}^{j-1}f(j)2^{frac{(i-j)(i-j-1)}{2}}$。
C拆掉,$f(i)=2^{frac{i(i-1)}{2}}-sum_{j=1}^{i-1}frac{f(j)(i-1)!2^{frac{(i-j)(i-j-1)}{2}}}{(j-1)!(i-j)!}$
按照套路,两边除$(i-1)!$,$frac{f(i)}{(i-1)!}=frac{2^{frac{i(i-1)}{2}}}{(i-1)!}-sum_{j=1}^{i-1}frac{f(j)2^{frac{(i-j)(i-j-1)}{2}}}{(j-1)!(i-j)!}$
有相似的形式,很好!!!令$g(i)=frac{f(i)}{(i-1)!}$,其中$g(0)=0$,$h(i)=frac{2^{frac{i(i-1)}{2}}}{i!}$,其中$h(0)=0$,$s(i)=frac{2^{frac{i(i-1)}{2}}}{(i-1)!}$,其中$s(0)=0$。
搞出他们三人的生成函数,可知$g=s-g*h$,得$g=frac{s}{1+h}$,好!多项式求逆再乘一次。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<map> 6 #include<math.h> 7 //#include<time.h> 8 //#include<complex> 9 #include<algorithm> 10 using namespace std; 11 12 int n,m; 13 #define maxn 262222 14 const int mod=1004535809,G=3; int rev[maxn]; 15 16 int powmod(int a,int b) 17 { 18 int ans=1; 19 while (b) 20 { 21 if (b&1) ans=1ll*ans*a%mod; 22 a=1ll*a*a%mod; b>>=1; 23 } 24 return ans; 25 } 26 27 void dft(int *a,int n,int type) 28 { 29 int wei=-1,tnt=n; while (tnt) wei++,tnt>>=1; 30 for (int i=0;i<n;i++) 31 { 32 rev[i]=0; 33 for (int j=0;j<wei;j++) rev[i]|=((i>>j)&1)<<(wei-j-1); 34 } 35 for (int i=0;i<n;i++) if (i<rev[i]) {int t=a[i]; a[i]=a[rev[i]]; a[rev[i]]=t;} 36 for (int i=1;i<n;i<<=1) 37 { 38 int w=powmod(G,(mod-1)/(i<<1)); 39 if (type==-1) w=powmod(w,mod-2); 40 for (int j=0,p=i<<1;j<n;j+=p) 41 { 42 int t=1; 43 for (int k=0;k<i;k++,t=1ll*t*w%mod) 44 { 45 int tmp=1ll*t*a[j+k+i]%mod; 46 a[j+k+i]=(a[j+k]-tmp+mod)%mod; 47 a[j+k]=(a[j+k]+tmp)%mod; 48 } 49 } 50 } 51 if (type==-1) 52 { 53 int inv=powmod(n,mod-2); 54 for (int i=0;i<n;i++) a[i]=1ll*a[i]*inv%mod; 55 } 56 } 57 58 void mul(int *a,int *b,int *c) 59 { 60 dft(a,n,1); dft(b,n,1); 61 for (int i=0;i<n;i++) c[i]=1ll*i[a]*i[b]%mod; 62 dft(c,n,-1); 63 } 64 65 int tmp[maxn]; 66 void nee(int *a,int n,int *ans) 67 { 68 if (n==1) {ans[0]=powmod(a[0],mod-2); return;} 69 nee(a,n>>1,ans); 70 for (int i=0;i<(n>>1);i++) tmp[i]=a[i]; for (int i=(n>>1);i<n;i++) tmp[i]=0; 71 dft(ans,n,1); dft(tmp,n,1); 72 for (int i=0;i<n;i++) ans[i]=((ans[i]+ans[i]-1ll*ans[i]*ans[i]%mod*tmp[i]%mod)+mod)%mod; 73 dft(ans,n,-1); for (int i=(n>>1);i<n;i++) ans[i]=0; 74 } 75 76 int s[maxn],g[maxn],h[maxn],u[maxn],fac[maxn],inv[maxn],two[maxn],tt[maxn]; 77 int main() 78 { 79 scanf("%d",&n); 80 fac[0]=1; for (int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod; 81 inv[n]=powmod(fac[n],mod-2); for (int i=n;i;i--) inv[i-1]=1ll*inv[i]*i%mod; 82 two[0]=1; for (int i=1;i<=n;i++) two[i]=(two[i-1]<<1)%mod; 83 tt[0]=0; for (int i=1;i<=n;i++) if (i&1) tt[i]=powmod(two[i>>1],i); else tt[i]=powmod(two[i>>1],i-1); 84 s[0]=0; for (int i=1;i<=n;i++) s[i]=1ll*tt[i]*inv[i-1]%mod; 85 h[0]=1; for (int i=1;i<=n;i++) h[i]=1ll*tt[i]*inv[i]%mod; 86 87 m=n+n; for (n=1;n<=m;n<<=1); m>>=1; 88 nee(h,n,u); mul(u,s,g); 89 printf("%lld ",1ll*g[m]*fac[m-1]%mod); 90 return 0; 91 }