首页 > 其他 > 详细

bzoj1478 Sgu282 Isomorphism

时间:2018-02-25 21:28:11      阅读:448      评论:0      收藏:0      [点我收藏+]

这道题也是一道不错的找规律polya原理的题

我们可以发现,对于两种点的置换,如果他们的循环节完全一样,那么他们对于边的置换的循环也完全一样。

我们又会发现,当一条边两侧的点位于同一循环中时,这些边构成的循环节共有${\frac{L_{i}}{2}}$个,$L_{i}$表示点的循环节长度

当两点位于两个循环中时,这些变构成的循环节共有$gcd(L_{i},L_{j})$个。

然后我们需要算出每种点的置换的方案数,这个写着不方便,看代码吧

于是我们可以dfs出每种点的置换,然后求出对应边的置换的循环节数以及方案数,最后上polya就好了!

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #define int long long
 7 using namespace std;
 8 int n,m,mod;
 9 int qp(int a,int b){
10     int c=1;
11     while(b){
12         if(b&1)c=c*a%mod;
13         a=a*a%mod; b>>=1;
14     }return c;
15 }
16 int l[66],C[66][66],fac[66],ny[66],g[66][66];
17 int gcd(int a,int b){return !b?a:gcd(b,a%b);}
18 int all,cnt,sum,ans;
19 void dfs(int x,int last,int num){
20     if(x==n+1){
21         sum=0;
22         for(int i=1;i<=num;i++)sum+=l[i]/2;
23         for(int i=1;i<=num;i++)
24             for(int j=i+1;j<=num;j++)sum+=g[l[i]][l[j]];
25         cnt=1;
26         for(int i=1,rest=n,j;i<=num;i++){
27             j=i;
28             while(j<=num&&l[j]==l[i]){
29                 (cnt*=C[rest][l[j]]*fac[l[j]-1]%mod)%=mod;
30                 rest-=l[j];j++;
31             }
32             (cnt*=ny[j-i])%=mod;
33             i=j-1;
34              
35         }
36         (all+=cnt)%=mod;
37         (ans+=cnt*qp(m,sum)%mod)%=mod;
38         return ;
39     }
40     for(int i=last;x+i<=n+1;i++){
41         l[num+1]=i;
42         dfs(x+i,i,num+1);
43     }
44 }
45 signed main(){
46     scanf("%lld%lld%lld",&n,&m,&mod);
47     fac[0]=1;
48     for(int i=1;i<=n;i++){
49         fac[i]=i*fac[i-1]%mod;
50         ny[i]=qp(fac[i],mod-2);
51     }
52     for(int i=1;i<=n;i++)
53         for(int j=1;j<=n;j++)g[i][j]=g[j][i]=gcd(i,j);
54     for(int i=0;i<=n;i++){
55         C[i][0]=1;
56         for(int j=1;j<=i;j++)
57             C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
58     }
59     dfs(1,1,0);
60     ans=(ans*qp(all,mod-2))%mod;
61     printf("%lld\n",ans);
62     return 0;
63 }
View Code

 

bzoj1478 Sgu282 Isomorphism

原文:https://www.cnblogs.com/Ren-Ivan/p/8470530.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!