BZOJ3456: 城市规划

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\n",1ll*g[m]*fac[m-1]%mod);
90     return 0;
91 }
View Code

 

posted @ 2018-02-28 10:36  Blue233333  阅读(166)  评论(0编辑  收藏  举报