[Polya] BZOJ 1488 图的同构

 传送门:

http://blog.csdn.net/wzq_qwq/article/details/48035455


#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define P 997
using namespace std;

inline int Gcd(int a,int b)
{
	if (a<b) return Gcd(b,a);
	return !b?a:Gcd(b,a%b);
}

inline int Pow(int a,int b)
{
	int ret=1;
	for (;b;b>>=1,a=a*a%P)
		if (b&1)
			(ret*=a)%=P;
	return ret;
}

const int maxn=65;
int fac[maxn+5],inv[maxn+5];

inline void Pre()
{
	fac[0]=1;
	for (int i=1;i<=maxn;i++)
		(fac[i]=i*fac[i-1])%=P;
	inv[1]=1;
	for (int i=2;i<=maxn;i++)
		(inv[i]=(P-P/i)*inv[P%i])%=P;
	inv[0]=1;
	for (int i=1;i<=maxn;i++)
		(inv[i]*=inv[i-1])%=P;
}

int n,cnt,ans;
int val[65],num[65];

inline void dfs(int now,int left)
{
	if (left==0)
	{
		int ret=0;
		int bot=1;
		for (int i=1;i<=cnt;i++)
		{
			ret+=num[i]*(num[i]-1)/2*val[i]+val[i]/2*num[i];
			for (int j=i+1;j<=cnt;j++)
				ret+=num[i]*num[j]*Gcd(val[i],val[j]);
		}
		for (int i=1;i<=cnt;i++)
			(bot*=Pow(val[i],num[i])*fac[num[i]]%P)%=P;
		(bot=Pow(bot,P-2)*fac[n])%=P;
		(ans+=Pow(2,ret)*bot)%=P;
		return;
	}
	if (now>left) return;
	dfs(now+1,left);
	for (int i=1;i*now<=left;i++)
	{
		val[++cnt]=now; num[cnt]=i;
		dfs(now+1,left-now*i);
		cnt--;
	}	
}
int main()
{
	freopen("t.in","r",stdin);
	freopen("t.out","w",stdout);
	Pre();
//	for (int i=1;i<=60;i++)
//	{
		ans=0;
		scanf("%d",&n);
//		n=i;
		dfs(1,n);
		(ans*=inv[n])%=P;
		printf("%d\n",ans);
//	}
	return 0;
}


你可能感兴趣的:([Polya] BZOJ 1488 图的同构)