[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”,问本质不同的环有多少个(不 ...
随机推荐
- ---Mock---基本使用
一.mock解决的问题 开发时,后端还没完成数据输出,前端只好写静态模拟数据.数据太长了,将数据写在js文件里,完成后挨个改url.某些逻辑复杂的代码,加入或去除模拟数据时得小心翼翼.想要尽可能还原真 ...
- python+selenium上传文件——input标签
我们要区分出上传按钮的种类,大体上可以分为两种: 第一种普通上传:将本地文件路径作为一个值,放在input标签中,通过form表单将这个值提交给服务器: 第二种插件上传:是通过Flash.JavaSc ...
- 万万没想到,Spring Boot 竟然这么耗内存!
Spring Boot总体来说,搭建还是比较容易的,特别是Spring Cloud全家桶,简称亲民微服务. 但在发展趋势中,容器化技术已经成熟,面对巨耗内存的Spring Boot,小公司表示用不起. ...
- SI 和 MDK 添加Astyle功能
一. 什么是Astyle 1. Astyle是一个用来对C/C++代码进行格式化的插件,可在多个环境中使用.该插件基于 Artistic Style 开发 二. 软件获取地址 1.下载地址:https ...
- MyBatis一个对多个主键(索引)生成实体类的处理
原数据库表: 生成实体类,多出了一个xxKey.java
- O-超大型LED显示屏
Input 输入包含不超过100组数据.每组数据第一行为”START hh:mm:ss”,表示比赛开始时刻为hh:mm:ss.最后一行为”END hh:mm:ss”,即比赛结束时刻.二者之间至少会有一 ...
- POJ 3259 Wormholes SPFA算法题解
版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...
- 微信小程序css篇----flex模型
一.Flex布局是什么? Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为Flex布局. .box{displ ...
- 115-基于TI TMS320DM6467无操作系统Camera Link智能图像分析平台
基于TI TMS320DM6467无操作系统Camera Link智能图像分析平台 1.板卡概述 该板卡是我公司推出的一款具有高可靠性.效率大化.无操作系统的智能视频处理卡,是机器视觉开发上的选. ...
- git分支管理与tag的学习笔记
git分支管理学习笔记:创建dev分支:git branch dev查看分支:git branch切换分支:git checkout dev创建并切换分支:git checkout dev -b zh ...