BZOJ 1488: [HNOI2009]图的同构 [Polya]

完全图中选出不同构的简单图有多少个

上题简化版,只有两种颜色....直接copy就行了

太诡异了,刚才电脑上多了一个不动的鼠标指针,然后打开显卡管理界面就没了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=65,P=997;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,m=2;
int inv[N],fac[N],facInv[N];
void ini(){
    inv[1]=1;fac[0]=facInv[0]=1;
    for(int i=1;i<=n;i++){
        if(i!=1) inv[i]=-P/i*inv[P%i]%P;
        if(inv[i]<0) inv[i]+=P;
        fac[i]=fac[i-1]*i%P;
        facInv[i]=facInv[i-1]*inv[i]%P;
    }
}
int L[N],tot;
int sum,ans;
inline int gcd(int a,int b){return b==0 ? a : gcd(b,a%b);}
inline int Pow(int a,int b){
    int re=1;
    for(;b;b>>=1,a=a*a%P)
        if(b&1) re=re*a%P;
    return re;
}
inline void mod(int &x){if(x>=P) x-=P;}
void dfs(int d,int now){
    if(d==n){
        int lo=0;
        int cnt=fac[n],same=1;
        sort(L+1,L+1+tot);
        for(int i=1;i<=tot;i++){
            lo+=L[i]/2;
            for(int j=i+1;j<=tot;j++) lo+=gcd(L[i],L[j]);

            cnt=cnt*inv[L[i]]%P;
            if(i!=1&&L[i]==L[i-1]) same++;
            else if(same!=1) cnt=cnt*facInv[same]%P,same=1;
        }
        if(same!=1) cnt=cnt*facInv[same]%P;
        mod(sum+=cnt);
        mod(ans+=cnt%P*Pow(m,lo)%P);
    }else{
        for(int j=now;d+j<=n;j++){
            L[++tot]=j;
            dfs(d+j,j);
            tot--;
        }
    }
}
int main(){
    //freopen("in","r",stdin);
    n=read();
    ini();
    dfs(0,1);
    ans=ans*Pow(sum,P-2)%P;
    printf("%d",ans);
}

 

posted @ 2017-03-01 15:29  Candy?  阅读(317)  评论(0编辑  收藏  举报