lgP4727 [HNOI2009]图的同构计数

#include<bits/stdc++.h>
#define MAXN 65
typedef long long ll;
using namespace std;


int n,m;
int mod;
int jc[MAXN],inv[MAXN],ans,inv2[MAXN];
int gcd(int a , int b){
	if(!b)return a;
	return gcd(b , a % b);
}
int poww(int x , int y){
	int zz = 1;
	while(y){
		if(y & 1)zz = 1ll * zz * x % mod;
		x = 1ll * x * x % mod;
		y = y >> 1;
	}
	return zz;
}

void init(){
	jc[0] = 1;for(int i = 1 ; i <= 60 ; i++)jc[i] = 1ll * jc[i - 1] * i % mod;
	for(int i = 0 ; i <= 60 ; i++)inv[i] = poww(jc[i] , mod - 2);
	for(int i = 0 ; i <= 60 ; i++)inv2[i] = poww(i , mod - 2);
}

int jl[MAXN];

void dfs(int now , int rest , int last){
	if(!rest){
		
		int zz = 0;
		for(int i = 1 ; i < now ; i++)
			for(int j = 1 ; j < i ; j++)
				zz = zz + gcd(jl[i] , jl[j]);
		
		for(int i = 1 ; i < now ; i++)zz = zz + jl[i] / 2;
		zz = poww(m , zz);
		for(int i = 1 ; i < now ; i++)zz = 1ll * zz * inv2[jl[i]] % mod;
		int last = (-1) , cnt = 0;
		for(int i = 1 ; i < now ; i++){
			if(jl[i] != last){
				zz = 1ll * zz * inv[cnt] % mod;
				cnt = 0 , last = jl[i];
			}
			cnt++;
		}
		zz = 1ll * zz * inv[cnt] % mod;
		ans = (ans + zz) % mod;
		
		
		
		return;
	}
	if(rest < last)return;
	for(int i = last ; i <= rest ; i++){
		if(rest - i <= i && rest - i == 0)break;
		jl[now] = i;
		dfs(now + 1 , rest - i , i);
	}
	if(rest >= last)jl[now] = rest , dfs(now + 1 , 0 , rest);
	
}

int main(){
	scanf("%d%d%d" , &n , &m , &mod);
	init();
	dfs(1 , n , 1);
	cout<<ans<<endl;
}
上一篇:Codeforces Round #754 (Div. 2)E 待写


下一篇:[HAOI2010]计数题解