zoukankan      html  css  js  c++  java
  • BZOJ 1488: [HNOI2009]图的同构 polay

    题意:两个图AB同构:把A的顶点重新编号后与B一模一样。求n个顶点的图一共有多少个?(同构的算一种)

    思路:边有n*(n-1)/2,这些边可以有可以没有,所以等同于边的颜色有两种。然后将n划分成循环节的和,n=L1+L2+……+Lm。现在需要把点置换映射到边置换。两个边在一个点循环节(大小L)时边置换循环节为L/2,否则为Gcd(L1,L2)。然后就是计算(L1,L2,……,Lm)这种划分的个数,设m个循环有t种数字,每种数字个数p1,p2,……,pt,那么划分个数为:n!/(L1*L2……*Lm*p1!*……*pt!)。

    const int mod=997;
     
    int p[N];
    int n;
    int f[N][2],cnt;
     
    void init()
    {
        p[0]=1;
        int i;
        for(i=1;i<N;i++) p[i]=p[i-1]*i%mod;
    }
     
    int ans;
     
     
    void cal()
    {
        i64 x=0,i,j;
        FOR0(i,cnt)
        {
            x+=f[i][0]/2*f[i][1]+(f[i][1]-1)*f[i][1]/2*f[i][0];
            for(j=i+1;j<cnt;j++) x+=f[i][1]*f[j][1]*Gcd(f[i][0],f[j][0]);
        }
        i64 pp=1;
        FOR0(i,cnt) pp=pp*myPow(f[i][0],f[i][1],mod)%mod*p[f[i][1]]%mod;
        pp=p[n]*gcdReverse(pp,mod)%mod;
     
        ans+=myPow(2,x,mod)*pp%mod;
        ans%=mod;
    }
     
    void DFS(int t,int re)
    {
        if(re==0)
        {
            cal();
            return;
        }
        if(t>re) return;
        DFS(t+1,re);
        int i;
        for(i=1;i*t<=re;i++)
        {
            f[cnt][0]=t;
            f[cnt++][1]=i;
            DFS(t+1,re-i*t);
            cnt--;
        }
    }
     
    int main()
    {
        init();
        RD(n);
        DFS(1,n);
        ans=ans*gcdReverse(p[n],mod)%mod;
        PR(ans);
    }
    
  • 相关阅读:
    网摘习惯
    关于Application.DoEvents()
    五句话足以改变一生
    ActionForm中reset()的用法
    Java的MD5加密和解密类
    ibatis主键自动生成
    Parameter index out of range (3 > number of parameters
    ibatis 2.0 3.0 DTD
    SmartUpload在servlet中使用方法
    The prefix "tx" for element "tx:annotationdriven" is not bound.
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/3803824.html
Copyright © 2011-2022 走看看