组合计数(polya计数):SGU 282 Isomorphism

Posted 既然选择了远方,便只顾风雨兼程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合计数(polya计数):SGU 282 Isomorphism相关的知识,希望对你有一定的参考价值。

  因为论文的题解写得太好了,直接贴。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 typedef long long LL;
 6 const int N=55;int st[N];
 7 LL n,m,Mod,fac[N],ifac[N],pow[N],ans;
 8 LL Inv(LL x){return x==1?x:(Mod-Mod/x)*Inv(Mod%x)%Mod;}
 9 LL Gcd(LL a,LL b){return b?Gcd(b,a%b):a;}
10 void DFS(int d,int c,int l){
11     if(c==0){
12         LL tot=1;int t=0;
13         for(int i=1;i<=d;i++)
14             tot=tot*Inv(st[i])%Mod;
15         for(int i=1;i<=d;i++)
16             if(st[i]!=st[i-1]){
17                 tot=tot*ifac[t]%Mod;
18                 t=1;
19             }
20             else t+=1;
21         tot=tot*ifac[t]%Mod;
22         for(int i=1;i<=d;i++)
23             tot=tot*pow[st[i]/2]%Mod;
24         for(int i=1;i<=d;i++)
25             for(int j=i+1;j<=d;j++)
26                 tot=tot*pow[Gcd(st[i],st[j])]%Mod;
27         ans=(ans+tot)%Mod;        
28     }
29     for(int i=l;i<=c;i++)
30         st[d+1]=i,DFS(d+1,c-i,i);
31 }
32 int main(){
33     scanf("%I64d%I64d%I64d",&n,&m,&Mod);
34     pow[0]=fac[0]=ifac[0]=1;
35     for(int i=1;i<=n;i++){
36         fac[i]=1ll*fac[i-1]*i%Mod;
37         pow[i]=pow[i-1]*m%Mod;
38         ifac[i]=Inv(fac[i]);
39     }
40     DFS(0,n,1);printf("%I64d\\n",ans);
41     return 0;
42 }

 

以上是关于组合计数(polya计数):SGU 282 Isomorphism的主要内容,如果未能解决你的问题,请参考以下文章

组合数学之Polya计数

bzoj1478 Sgu282 Isomorphism

SGU - 282

Polya定理

poj1286 polya计数法

hdu 5080 2014ACM/ICPC鞍山K题 polya计数