• BZOJ 3456: 城市规划


    3456: 城市规划

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 640  Solved: 352
    [Submit][Status][Discuss]

    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

    分析:

    有两种方法:

    一种是直接计算方案数

    一种是用总的方案数减去不合法的方案数

    如果直接计算:

    我们定义$f[i]$为点数为$i$的无向连通图的数量,我们考虑已经计算出了前$n-1$个点的答案,考虑新加入第$n$号节点,这个$n$号节点一定是联通了之前的若干个联通块,所以我们枚举$1$号节点所在的联通块的大小$s$,那么$n$号节点和$1$号节点所在的联通块联通的方案有$2^s-1$种,这个联通块的方案为$f[s]$,剩下的$n-s$个点就是一个子问题了也就是$f[n-s]$,那么最后的式子就是:$sum _{s=1}^{n-1} extrm{C}_{n-2}^{s-1}f[n-s]f[s](2^s-1)$

    发现这是一个分治$NTT$,然而复杂度貌似是$O(Nlog^2N)$的...

    另一种计算补集的方法的复杂度就优秀了一点:

    定义$f[i]$代表点数为$i$的无向联通图的数量,考虑总的可能出现在图中的边有$ extrm{C}_{n}^{2}$种,那么生成图的数量就是$2^{ extrm{C}_{n}^{2}}$,现在我们考虑不合法的方案:依旧考虑$1$号节点所在的联通块大小为$s$,那么其他的$n-s$个点的子图随便排列,也就是说,不合法的为$sum _{j=1}^{i-1}f[j] extrm{C}_{i-1}^{j-1}2^{ extrm{C}_{i-j}^{2}}$...

    两边同时除以$(i-1)!$:

    $frac{ f[i] }{ (i-1)! }=frac{ 2^{ extrm{C}_{i}^{2}} }{ (i-1)! }-frac{sum _{j=1}^{i-1}f[j] extrm{C}_{i-1}^{j-1}2^{ extrm{C}_{i-j}^{2}}}{(i-1)!}$

    最后的式子长成酱紫:

    $sum_{j=1}^{i}frac{f[j]}{(j-1)!}*frac{ 2^{ extrm{C}_{i-j}^{2} } }{(i-j)!}=frac{2^{ extrm{C}_{i}^{2}}}{(i-1)!}$

    我们令$A=sum_{i=1}^{n}frac{f[i]}{(i-1)!}*x^i$

    $B=sum_{i=0}^{n}frac{2^{ extrm{C}_{i}^{2}}}{i!}*x^i$

    $C=sum_{i=1}^{n}frac{2^{ extrm{C}_{i}^{2}}}{(i-1)!}*x^i$

    那么$A*B=C$,我们可以得出$A=C*B^{-1}$,所以求个逆$NTT$一下就好了...

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    //by NeighThorn
    using namespace std;
    
    const int maxn=1000000+5,mod=1004535809,G=3;
    
    int n,m,L,N,R[maxn],a[maxn],b[maxn],c[maxn],d[maxn],fac[maxn],inv[maxn];
    
    inline int power(int x,long long y){
    	int res=1;
    	while(y){
    		if(y&1) res=1LL*res*x%mod;
    		x=1LL*x*x%mod,y>>=1;
    	}
    	return res;
    }
    
    inline void NTT(int *a,int f,int n,int L){
    	for(int i=0;i<n;i++)
    		R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    	for(int i=0;i<n;i++)
    		if(i<R[i]) swap(a[i],a[R[i]]);
    	for(int i=1;i<n;i<<=1){
    		int wn=power(G,(mod-1)/(i<<1));
    		if(f==-1) wn=power(wn,mod-2);
    		for(int j=0;j<n;j+=(i<<1)){
    			int w=1;
    			for(int k=0;k<i;k++,w=1LL*w*wn%mod){
    				int x=a[j+k],y=1LL*a[j+k+i]*w%mod;
    				a[j+k]=(x+y)%mod;
    				a[j+k+i]=(x-y+mod)%mod;
    			}
    		}
    	}
    	if(f==-1){
    		int tmp=power(n,mod-2);
    		for(int i=0;i<n;i++)
    			a[i]=1LL*a[i]*tmp%mod;	
    	}
    }
    
    inline void inverse(int *a,int *b,int n,int L){
    	if(n==1){
    		b[0]=power(a[0],mod-2);return;
    	}
    	inverse(a,b,n>>1,L-1);
    	memcpy(d,a,n*sizeof(int));
    	memset(d+n,0,n*sizeof(int));
    	NTT(d,1,n<<1,L+1);NTT(b,1,n<<1,L+1);
    	for(int i=0;i<n<<1;i++) b[i]=1LL*b[i]*((2-1LL*d[i]*b[i]%mod+mod)%mod)%mod;
    	NTT(b,-1,n<<1,L+1);
    	memset(b+n,0,n*sizeof(int));
    }
    
    signed main(void){
    	memset(a,0,sizeof(a));
    	memset(b,0,sizeof(b));
    	memset(c,0,sizeof(c));
    	scanf("%d",&n);fac[0]=1;
    	for(int i=1;i<=n;i++) fac[i]=1LL*fac[i-1]*i%mod;
    	inv[n]=power(fac[n],mod-2);
    	for(int i=n-1;i>=0;i--) inv[i]=1LL*inv[i+1]*(i+1)%mod;
    	m=n<<1;for(N=1;N<=m;N<<=1) L++;a[0]=1;
    	for(int i=1;i<=n;i++) a[i]=1LL*power(2,1LL*i*(i-1)/2)*inv[i]%mod;
    	for(int i=1;i<=n;i++) c[i]=1LL*power(2,1LL*i*(i-1)/2)*inv[i-1]%mod;
    	inverse(a,b,N,L);
    	NTT(b,1,N,L),NTT(c,1,N,L);
    	for(int i=0;i<N;i++) b[i]=1LL*b[i]*c[i]%mod;
    	NTT(b,-1,N,L);
    	printf("%d
    ",(int)(1LL*b[n]*fac[n-1]%mod));
    	return 0;
    }
    

      


    By NeighThorn

     
  • 相关阅读:
    TypeScript-基础-09-声明文件
    TypeScript-基础-08-类型断言
    TypeScript-基础-07-函数的类型
    TypeScript-基础-06-数组的类型
    TypeScript-基础-05-对象的类型—接口
    TypeScript-基础-04-联合类型
    TypeScript-工程
    小白学前端03
    小白学前端02
    小白学前端
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6657930.html
Copyright © 2020-2023  润新知