zoukankan      html  css  js  c++  java
  • 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

     
  • 相关阅读:
    poj 2312 Battle City
    poj 2002 Squares
    poj 3641 Pseudoprime numbers
    poj 3580 SuperMemo
    poj 3281 Dining
    poj 3259 Wormholes
    poj 3080 Blue Jeans
    poj 3070 Fibonacci
    poj 2887 Big String
    poj 2631 Roads in the North
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6657930.html
Copyright © 2011-2022 走看看