zoukankan      html  css  js  c++  java
  • [LuoguP4841]城市规划(多项式ln+生成函数)

    [LuoguP4841]城市规划(多项式ln+生成函数)

    题面

    (n)个顶点的有标号连通简单无向图的个数(简单指的是无重边自环)。((n leq 10^5))

    分析

    (n)个点的简单无向图有(2^{inom{n}{2}})个,设G是所有无向图,那么G的EGF为

    [G(x)=sum_{n=0}^{infin} 2^{inom{n}{2}} frac{x^n}{n!} ]

    设连通图的生成函数为(C(x)),考虑枚举连通块个数(i),有

    [G(x)=sum_{igeq 0}frac{1}{i!}C^i(x)=exp(C(x) ]

    (i!)是因为连通块内部的排列顺序无关。第二步用了(mathrm{e}^x)的泰勒展开式。多项式ln求出(C),复杂度(O(nlog n))

    代码

    #include<cstdio>
    #include<cstring>
    #define maxn 400000
    #define mod 1004535809 
    using namespace std;
    typedef long long ll;
    inline ll fast_pow(ll x,ll k){
    	ll ans=1;
    	while(k){
    		if(k&1) ans=ans*x%mod;
    		x=x*x%mod;
    		k>>=1;
    	}
    	return ans;
    }
    inline ll inv(ll x){
    	return fast_pow(x,mod-2); 
    }
    
    const ll G=3,invG=inv(3); 
    int rev[maxn*4+5];
    void NTT(ll *x,int n,int type){
        for(int i=0;i<n;i++) if(i<rev[i]) swap(x[i],x[rev[i]]); 
        for(int len=1;len<n;len*=2){
            int sz=len*2;
            ll gn1=fast_pow((type==1?G:invG),(mod-1)/sz);
            for(int l=0;l<n;l+=sz){
                int r=l+len-1;
                ll gnk=1;
                for(int i=l;i<=r;i++){
                    ll tmp=x[i+len];
                    x[i+len]=(x[i]-gnk*tmp%mod+mod)%mod;
                    x[i]=(x[i]+gnk*tmp%mod)%mod;
                    gnk=gnk*gn1%mod; 
                }
            }
        } 
        if(type==-1){
            ll invn=inv(n);
            for(int i=0;i<n;i++) x[i]=x[i]*invn%mod; 
        }
    }
    void poly_mul(ll *a,ll *b,ll *c,int n,int m){
    	static ll ta[maxn+5],tb[maxn+5];
    	int N=1,L=0;
    	while(N<n+m-1){
    		N*=2;
    		L++;
    	}
    	for(int i=0;i<n;i++) ta[i]=a[i];
    	for(int i=n;i<N;i++) ta[i]=0;
    	for(int i=0;i<m;i++) tb[i]=b[i];
    	for(int i=n;i<N;i++) tb[i]=0;
    	for(int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    	NTT(ta,N,1);
    	NTT(tb,N,1);
    	for(int i=0;i<N;i++) c[i]=ta[i]*tb[i]%mod;
    	NTT(c,N,-1);
    	for(int i=n+m-1;i<N;i++) c[i]=0;
    } 
    void poly_inv(ll *f,ll *g,int n){
    	static ll tmp[maxn+5];
    	if(n==1){
    		g[0]=inv(f[0]);
    		return;
    	}
    	poly_inv(f,g,(n+1)/2);
    	poly_mul(f,g,tmp,n,n);
    	poly_mul(tmp,g,tmp,n,n);
    	for(int i=0;i<n;i++) g[i]=(2*g[i]-tmp[i]+mod)%mod;
    }
    void poly_deriv(ll *f,ll *g,int n){
    	for(int i=1;i<n;i++) g[i-1]=f[i]*i%mod;
    	g[n-1]=0;
    } 
    void poly_inter(ll *f,ll *g,int n){
    	for(int i=n-1;i>=1;i--) g[i]=f[i-1]*inv(i)%mod;
    	g[0]=0;
    }
    void poly_ln(ll *f,ll *g,int n){
    	static ll invf[maxn+5];
    	poly_inv(f,invf,n);
    	poly_deriv(f,g,n);
    	poly_mul(g,invf,g,n,n);
    	poly_inter(g,g,n*2);
    	for(int i=n;i<n*2;i++) g[i]=0;
    }
    void poly_exp(ll *f,ll *g,int n){
    	static ll lng[maxn+5];
    	if(n==1){
    		g[0]=1;
    		return;
    	}
    	poly_exp(f,g,(n+1)/2);
    	poly_ln(g,lng,n);
    	for(int i=0;i<n;i++) lng[i]=(f[i]-lng[i]+mod)%mod;
    	lng[0]++;
    	poly_mul(g,lng,g,n,n);
    	for(int i=n;i<n*2;i++) g[i]=0;
    }
    
    int n;
    ll fact[maxn+5];
    ll c[maxn+5],f[maxn+5];
    int main(){
    	scanf("%d",&n);
    	fact[0]=1;
    	for(int i=1;i<=n;i++) fact[i]=fact[i-1]*i%mod;
    	for(int i=0;i<=n;i++) c[i]=fast_pow(2,1ll*i*(i-1)/2)*inv(fact[i])%mod;
    	poly_ln(c,f,n+1);
    	printf("%lld
    ",f[n]*fact[n]%mod);
    }
    
  • 相关阅读:
    Echarts动态加载柱状图和折线图混合展示的实例
    Webdynpro ABAP 简单剖析
    SAP NetWeaver Business Client (NWBC) 简介
    nginx and node.js配合使用 helloworld
    Nodejs连接mysql的增、删、改、查操作
    SAPUI5使用了哪些开源技术
    Javascript 严格模式详解
    SAPUI5实例一:来创建Web应用UI
    OPEN(SAP) UI5 学习入门系列之四:更好的入门系列-官方Walkthrough
    OPEN(SAP) UI5 学习入门系列之三:MVC (下)
  • 原文地址:https://www.cnblogs.com/birchtree/p/13426883.html
Copyright © 2011-2022 走看看