zoukankan      html  css  js  c++  java
  • HDU5552 Bus Routes (CDQ+NTT)

    HDU-5552 Bus Routes (CDQ+NTT)

    这道题的本质其实是求\(n\)个点带环联通图的数量

    实际上就是\(n\)个点联通图的数量减去树的数量

    树的数量可以通过\(Prufer\)序列得到是\(n^{n-2}\),这个东西去问度娘吧

    \(n\)个点联通图的数量你可以去做 BZOJ-3456 详细题解

    注意这道题比较特殊,\(n\)个点随意的方案数是\((m+1)^{n(n-1)/2}\)

    #include<bits/stdc++.h>
    using namespace std;
    
    #define reg register
    typedef long long ll;
    #define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
    
    char IO;
    int rd(){
    	int s=0;
    	while(!isdigit(IO=getchar()));
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return s;
    }
    
    const ll N=2e4+10,P=152076289;
    const ll G=106,IG=101862420;
    
    ll qpow(ll x,ll k){
    	ll res=1;
    	for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
    	return res;
    }
    
    int n,m;
    ll Inv[N],Fac[N],Pow[N];
    ll dp[N],g[N];
    int rev[N];
    void NTT(int n,ll *a,int f) {
    	rep(i,1,n-1) if(rev[i]<i) swap(a[i],a[rev[i]]);
    	for(reg int i=1;i<n;i<<=1) {
    		ll w=qpow(f==1?G:IG,(P-1)/i/2);
    		for(reg int l=0;l<n;l+=2*i) {
    			ll e=1;
    			for(reg int j=l;j<l+i;j++,e=e*w%P) {
    				ll t=a[j+i]*e%P;
    				a[j+i]=(a[j]-t)%P;
    				a[j]=(a[j]+t)%P;
    			}
    		}
    	}
    	if(f==-1) {
    		ll base=qpow(n,P-2);
    		rep(i,0,n-1) a[i]=a[i]*base%P;
    	}
    }
    
    ll A[N],B[N],C[N];
    
    
    void Solve(int l,int r){ 
    	if(l==r) return;
    	int mid=(l+r)>>1;
    	Solve(l,mid);
    	int R=1,cc=-1;
    	while(R<=r-l+2) R<<=1,cc++;
    	rep(i,1,R) rev[i]=(rev[i>>1]>>1)|((i&1)<<cc);
    	rep(i,0,R) A[i]=B[i]=0;
    	rep(i,l,mid) A[i-l]=-dp[i]*Inv[i-1]%P;
    	rep(i,1,r-l+1) B[i]=g[i]*Inv[i]%P;
    	NTT(R,A,1),NTT(R,B,1);
    	rep(i,0,R) A[i]=A[i]*B[i]%P;
    	NTT(R,A,-1);
    	rep(i,mid+1,r) dp[i]=(dp[i]+A[i-l]*Fac[i-1])%P;
    	Solve(mid+1,r);
    }
    
    int main(){
    	Inv[0]=Inv[1]=Fac[0]=Fac[1]=1;
    	rep(i,2,N-1) {
    		Fac[i]=Fac[i-1]*i%P;
    		Inv[i]=(P-P/i)*Inv[P%i]%P;
    	}
    	rep(i,2,N-1) Inv[i]=Inv[i-1]*Inv[i]%P;
    	rep(kase,1,rd()) {
    		n=rd(),m=rd();
    		rep(i,1,n) g[i]=dp[i]=qpow(m%P+1,i*(i-1)/2);
    		Solve(1,n);//CDQ求出联通图的方案数
    		ll ans=dp[n]-qpow(m,n-1)*qpow(n,n-2)%P;
    		ans=(ans%P+P)%P;
    		printf("Case #%d: %lld\n",kase,ans);
    	}
    }
    
    
    
    
    
    
  • 相关阅读:
    Knime 使用 初探
    MySql可视化工具MySQL Workbench使用教程
    MySQL导入sql 文件的5大步骤
    Import MySQL Dumpfile, SQL Datafile Into My Database
    导入已有的vmdk文件,发现网络无法连通
    VirtualBox镜像复制载入
    对自己说的话
    linux遇见的问题
    vbox下安装 linux 64 bit出现“kernel requires an x86_64 cpu
    Servlet 3 HttpServletRequest HttpServletResponse 验证码图片 form表单
  • 原文地址:https://www.cnblogs.com/chasedeath/p/12103411.html
Copyright © 2011-2022 走看看