记录编号 |
98630 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[SGU U282][JSOI 2006]同构 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
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;
}