[BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理
分析
三倍经验题,本文以[BZOJ1478][SGU282]Isomorphism为例展开叙述,主体思路与另外两题大(wan)致(quan)相(yi)同(zhi)。
这可能是博主目前写过最长也是最认真的题解了。
题目中规定“若两个已染色的图,其中一个图可以通过结点重新编号而与另一个图完全相同, 就称这两个染色方案相同”,说明这个置换群是定义在点上的,而染色方案是定义在边上的。把边的染色方案转化为点的染色方案不太现实,所以说我们可以考虑如何将点的置换转化为边的置换。
一个显然的结论是点的置换和边的置换是一一对应的,但是我们不能暴力枚举所有的点的置换,因为可以想到点的置换又可以和\(1 \sim n\)的排列一一对应,推出共有\(n!\)个点的置换。换一个角度考虑,一个点的置换是由多个循环节组成的,所以我们可以暴力枚举每个循环节的长度,直接由此转化为边的置换,计算出此时的边的置换的循环节个数后乘一个满足这种循环节长度组合的点的置换的个数,这样的复杂度是可以接受的。
假设我们枚举到这样一个数组\(cnt\),\(cnt[i]\)表示在这种点的置换中循环节长度为\(i\)的循环节有\(cnt[i]\)个。
考虑一个长度为\(l\)的点的置换的循环节,现在有两个结点都在这个循环节上,这样的两个结点会形成\(\lfloor \frac{l}{2} \rfloor\)个边的置换的循环节。
为什么?
1----6 考虑这样一个点的置换的循环节(1,2,3,4,5,6)(逆时针),
/ \ 会形成6/2=3个边的置换的循环节,分别为:
/ \ ((1,2),(2,3),(3,4),(4,5),(5,6),(6,1))
2 5 ((1,3),(2,4),(3,5),(4,6),(5,1),(6,2))
\ / ((1,4),(2,5),(3,6))
\ / 由于边是无向边,以上便是全部的3个边的置换的循环节。
3----4 点的置换的循环节长度为奇数时情况稍有不同。
如果两个结点中有一个在另一个长度为\(l'\)的循环节上,那么这样的两个结点会形成\(\frac{l \times l'}{lcm(l,l')}=gcd(l,l')\)个边的置换的循环节。
把所有以上两种边的置换的循环节的个数加起来就好了。
以上,我们已经得到了此时的边的置换的循环节个数,接下来我们想求出满足这种循环节长度组合的点的置换的个数。(又开始啰嗦了)
假设我们有一个\(1 \sim n\)的排列(注意这里要和前文所提到的“点的置换可以和\(1 \sim n\)的排列一一对应”进行区分,它们不一样!),可以从左到右在这个排列中截出\(cnt[1]\)个\(1\),\(cnt[2]\)个\(2\),......,以此类推。每一段截出来的数字我们可以认为这是一个点的置换的循环节。我们知道长度\(1 \sim n\)的排列有\(n!\)个,又注意到循环节关心的是每个数字的下一个是什么,而不关心第几个数字是什么,所以要排列数要除以\(\prod i^{cnt[i]}\)。又双注意到对于长度相同的几个循环节,我们其实不会区分它们,更不会考虑它们的先后顺序,所以又要除以\(\prod (cnt[i]!)\)。综上所述,满足这种循环节长度组合的点的置换的个数为:
\]
根据Polya定理,把求出来的两坨东西搞一搞,最后乘一个\((n!)^{-1}\)即可。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#define rin(i,a,b) for(int i=(a);i<=(b);i++)
#define rec(i,a,b) for(int i=(a);i>=(b);i--)
#define trav(i,x) for(int i=head[(x)];i;i=e[i].nxt)
using std::cin;
using std::cout;
using std::endl;
typedef long long LL;
const int MAXN=55;
const int MAXM=1005;
int n,m;LL MOD,ans=0;
int cnt[MAXN];
LL fac[MAXN];
inline LL gcd(LL x,LL y){
if(!x||!y) return x+y;
while(y){
std::swap(x,y);
y%=x;
}
return x;
}
inline LL qpow(LL x,LL y){
LL ret=1,tt=x%MOD;
while(y){
if(y&1) ret=ret*tt%MOD;
tt=tt*tt%MOD;
y>>=1;
}
return ret;
}
void dfs(int rem,int now){
if(!rem){
LL temp=0,mot=1;
rin(i,1,now-1){
if(!cnt[i]) continue;
temp+=i/2*cnt[i];
temp+=i*cnt[i]*(cnt[i]-1)/2;
rin(j,i+1,now-1){
if(!cnt[j]) continue;
temp+=cnt[i]*cnt[j]*gcd(i,j);
}
}
rin(i,1,now-1){
if(!cnt[i]) continue;
mot=mot*qpow(i,cnt[i])%MOD*fac[cnt[i]]%MOD;
}
ans=(ans+qpow(m,temp)*fac[n]%MOD*qpow(mot,MOD-2))%MOD;
return;
}
if(now>rem) return;
for(int i=0;i*now<=rem;i++){
cnt[now]=i;
dfs(rem-i*now,now+1);
}
}
int main(){
scanf("%d%d%lld",&n,&m,&MOD);
fac[0]=1;
rin(i,1,n) fac[i]=fac[i-1]*i%MOD;
dfs(n,1);
printf("%lld\n",ans*qpow(fac[n],MOD-2)%MOD);
return 0;
}
[BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理的更多相关文章
- 【BZOJ1478】Sgu282 Isomorphism Pólya定理神题
[BZOJ1478]Sgu282 Isomorphism 题意:用$m$种颜色去染一张$n$个点的完全图,如果一个图可以通过节点重新标号变成另外一个图,则称这两个图是相同的.问不同的染色方案数.答案对 ...
- bzoj 1488: [HNOI2009]图的同构【polya定理+dfs】
把连边和不连边看成黑白染色,然后就变成了 https://www.cnblogs.com/lokiii/p/10055629.html 这篇讲得好!https://blog.csdn.net/wzq_ ...
- BZOJ1478 Sgu282 Isomorphism
Problem A: Sgu282 Isomorphism Time Limit: 15 Sec Memory Limit: 64 MBSubmit: 172 Solved: 88[Submit] ...
- BZOJ 1815: [Shoi2006]color 有色图(Polya定理)
题意 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图. 如果两张有色图有相同数量的顶点,而且经过某种顶点编号的重排,能够使得 ...
- bzoj1478:Sgu282 Isomorphism
思路:由于题目中是通过改变点的编号来判断两种染色方案是否相同,而染色的确是边,于是考虑如何将点置换转化为边置换. 对于一个有n个点的完全图,其点置换有n!个(即全排列个数),又由于每一个边置换都对应了 ...
- 「算法笔记」Polya 定理
一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...
- 【BZOJ 1478】 1478: Sgu282 Isomorphism (置换、burnside引理)
1478: Sgu282 Isomorphism Description 给 定一个N 个结点的无向完全图( 任意两个结点之间有一条边), 现在你可以用 M 种颜色对这个图的每条边进行染色,每条边必须 ...
- 【转】Polya定理
转自:http://endlesscount.blog.163.com/blog/static/82119787201221324524202/ Polya定理 首先记Sn为有前n个正整数组成的集合, ...
- 【群论】polya定理
对Polya定理的个人认识 我们先来看一道经典题目: He's Circles(SGU 294) 有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不 ...
随机推荐
- redis学习(二)
深入了解redis字符串,列表,散列和有序集合命令,了解发布,订阅命令和其他命令. 一,字符串 1.字符串可以存储3种类型的值 字符串,整数,浮点数 2.运算命令列表 incr : incr ...
- android开发错误经验总结
TextView: 1.textView.setText();参数如果直接传int类型,ide不会显示错误.但是运行会报错. 布局渲染: 1. <View android:background= ...
- RocketMQ高可用集群
集群支持: RocketMQ天生对集群的支持非常友好 单Master: 优点:除了配置简单没什么优点 缺点:不可靠,该机器重启或宕机,将导致整个服务不可用 多Master: 优点:配置简单,性能最高 ...
- 工具使用--Tomcat
一.Tomcat 服务搭建 1.进入apache官网下载tomcat 8.在左手边的菜单区,选择download下的tomcat8 版本: PS:操作系统,文件类型 2.将zip文件下载,解压到本地: ...
- CCF1078奇怪的电梯
这是一道dfs搜索题.(noi的题库测试数据有些水) 已知每一层的步数,有两个方向(上下),求解到达终点的最少操作数.拿到这个题就发现是一个Dfs,于是便套了模板写代码.Wa了三次才AC.核心是:1. ...
- QButtonGroup
单选按钮和多选按钮,存放进QButtonGroup中 QButtonGroup方法来实现分组:将相同功能的按键,设为一个分组,然后可以进行 单选 或 多选 或 互斥单选 QAbstractButton ...
- HDU-1018 BigNumber
Big Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- JVM — 性能调优
概念: 一:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.” ...
- POJ 3414 Pots (BFS/DFS)
Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7783 Accepted: 3261 Special Ju ...
- P4290 [HAOI2008]玩具取名
传送门 $dp$ 设 $f[i][j][k]$ 表示初始为 $k$ 时,能否得到 $[i,j]$ 这一段子串 设 $pd[i][j][k]$ 表示长度为二的字符串 $ij$ 能否由 $k$ 得到 然后 ...