zoukankan      html  css  js  c++  java
  • 51nod1252 桥与海港

    Link
    搞啥不好搞非素数模数。
    先枚举港口并将其视为根,那么要算的就是根的儿子数均(le k)的方案数。
    考虑枚举根的总儿子数(x),选出这些儿子有({n-mchoose x})种方案,把(x)个儿子挂在(m)个根上的方案数设为(f_{x,m}),然后把根删掉,剩下的就是(n-m)个点构成(x)棵有根树的方案数,这个可以Generalized Caylay算。
    (f_{x,m})等价于(x)个球染(m)种色,每种颜色的个数(le k)的方案数,转移考虑补集容斥,(f_{i,j}=j(f_{i-1,j}-{ichoose k}f_{i-k,j-1}))
    组合数可以用({nchoose m}=frac{n^{underline m}}m)算,然后模数不是质数所以代码多了1K。

    #include<cstdio>
    #include<cstring>
    using i64=long long;
    const int N=101;
    i64 read(){i64 x;scanf("%lld",&x);return x;}
    i64 P,tot,f[N][N*N],inv[N*N],fac[N],cnt[N],s1[N],s2[N],c[N*N][N];
    i64 inc(i64 a,i64 b){return a+=b,a>=P? a-P:a;}
    i64 dec(i64 a,i64 b){return a-=b,a<0? a+P:a;}
    i64 mul(i64 a,i64 b){return 1ull*a*b%P;}
    i64 pow(i64 a,i64 k){i64 r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    void exgcd(i64 a,i64 b,i64&x,i64&y){!b? (x=1,y=0):(exgcd(b,a%b,y,x),y-=a/b*x);}
    i64 cal(i64 x,i64 d,i64*s){for(int i=1;i<=tot;++i) while(!(x%fac[i])) s[i]=inc(s[i],d),x/=fac[i];return x;}
    i64 product(i64*s){i64 r=1;for(int i=1;i<=tot;++i) r=mul(r,pow(fac[i],s[i]));return r;}
    i64 C(int n,int m)
    {
        i64 a=1,b=1,x,y;memset(s1,0,sizeof s1);
        for(int i=n-m+1;i<=n;++i) a=mul(a,cal(i,1,s1));
        for(int i=1;i<=m;++i) b=mul(b,cal(i,P-1,s1));
        return exgcd(b,P,x,y),mul(mul(a,inc(x,P)),product(s1));
    }
    void FAC(i64 t)
    {
        memset(cnt+1,0,sizeof cnt),tot=0;
        for(i64 i=2;i*i<=t;++i) if(!(t%i)) for(fac[++tot]=i;!(t%i);t/=i,++cnt[tot]);
        if(t^1) fac[++tot]=t,cnt[tot]=1;
    }
    void solve()
    {
        int n=read(),m=read(),k=read();i64 ans=0;
        FAC(P=read()),memset(f,0,sizeof f),memset(s2,0,sizeof s2);
        for(int i=0,j;i<=10000;++i) for(j=c[i][0]=1;j<=i&&j<=100;++j) c[i][j]=inc(c[i-1][j-1],c[i-1][j]);
        for(int i=1;i<=m;++i)
        {
    	f[i][0]=1;
    	for(int j=1;j<=m*k;++j)
    	{
    	    f[i][j]=mul(i,f[i][j-1]);
    	    if(j>k) f[i][j]=dec(f[i][j],mul(mul(i,c[j-1][k]),f[i-1][j-k-1]));
    	}
        }
        for(i64 i=0,a=1,b=1,x,y;i<=m*k;++i)
    	if(n>i+m) ans=inc(ans,mul(mul(mul(mul(f[m][i],pow(n-m,n-i-m-1)),i),a),product(s2))),a=mul(a,cal(n-m-i,1,s2)),b=cal(i+1,P-1,s2),exgcd(b,P,x,y),b=inc(x,P),a=mul(a,b);
    	else if(n==i+m) ans=inc(ans,f[m][i]);
        printf("%lld
    ",mul(ans,C(n,m)));
    }
    int main(){for(i64 T=read();T;--T) solve();}
    
  • 相关阅读:
    网站制作教程之PageAdmin网站管理系统(cms)实现多域名访问
    免费企业网站模板_学校网站模板_政府网站模板源码下载
    网站建设如何挑选自助网站建设系统
    Problem2-Project Euler
    Problem1-Project Euler
    防微杜渐——读《C安全编码标准》
    3D射影不变量
    直线匹配-LPI算法原理 Robust line matching through line–point invariants
    angular-cli 工程中使用scss文件
    JS怎么计算html标签里文字的宽度
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12250564.html
Copyright © 2011-2022 走看看