记录编号 98630 评测结果 AAAAAAAAAA
题目名称 [SGU U282][JSOI 2006]同构 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 3.651 s
提交时间 2014-04-23 22:18:22 内存使用 0.31 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
const int SIZEN=60;
ll MOD;
ll inv;//逆元
ll L[SIZEN],K[SIZEN];
ll tot;
ll N,M,mul;
ll gcd(ll a,ll b){
	return !b?a:gcd(b,a%b);
}
ll quickpow(ll a,ll n){
	ll ans=1;
	a%=MOD;
	while(n){
		if(n&1) ans=(ans*a)%MOD;
		a=(a*a)%MOD;
		n>>=1;
	}
	return ans;
}
void init(void){
	tot=0;
	mul=1;
	memset(K,0,sizeof(K));
	for(ll i=2;i<=N;i++) mul=(mul*i)%MOD;
	inv=quickpow(mul,MOD-2);//inv=mul^-1
	//一共n!种置换
}
ll fact(ll a){//a!
	ll i,ans=1;
	for(int i=2;i<=a;i++) ans=(ans*i)%MOD;
	return ans;
}
ll DFS(ll left,ll limit){
	if(left==0){
		ll t1=1,t2=0;
		memset(K,0,sizeof(K));
		for(int i=0;i<tot;i++){
			t1=(t1*L[i])%MOD;
			t2+=L[i]/2;
			K[L[i]]++;
		}
		for(int i=1;i<=N;i++) t1=(t1*fact(K[i]))%MOD;
		for(int i=0;i<tot;i++) for(int j=i+1;j<tot;j++) t2+=gcd(L[i],L[j]);
		return (((mul*quickpow(t1,MOD-2))%MOD)*quickpow(M,t2))%MOD;
	}
	ll ans=0;
	for(int i=1;i<=limit&&i<=left;i++){
		L[tot++]=i;
		ans=(ans+DFS(left-i,i))%MOD;
		tot--;
	}
	return ans;
}
int main(){
	freopen("isomorphism.in","r",stdin);
	freopen("isomorphism.out","w",stdout);
	scanf("%lld%lld%lld",&N,&M,&MOD);
	init();
	printf("%lld\n",(DFS(N,N)*inv)%MOD);
	return 0;
}