分析

三倍经验题,本文以[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]!)\)。综上所述,满足这种循环节长度组合的点的置换的个数为:

\[\frac{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定理的更多相关文章

  1. 【BZOJ1478】Sgu282 Isomorphism Pólya定理神题

    [BZOJ1478]Sgu282 Isomorphism 题意:用$m$种颜色去染一张$n$个点的完全图,如果一个图可以通过节点重新标号变成另外一个图,则称这两个图是相同的.问不同的染色方案数.答案对 ...

  2. bzoj 1488: [HNOI2009]图的同构【polya定理+dfs】

    把连边和不连边看成黑白染色,然后就变成了 https://www.cnblogs.com/lokiii/p/10055629.html 这篇讲得好!https://blog.csdn.net/wzq_ ...

  3. BZOJ1478 Sgu282 Isomorphism

    Problem A: Sgu282 Isomorphism Time Limit: 15 Sec  Memory Limit: 64 MBSubmit: 172  Solved: 88[Submit] ...

  4. BZOJ 1815: [Shoi2006]color 有色图(Polya定理)

    题意 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图. 如果两张有色图有相同数量的顶点,而且经过某种顶点编号的重排,能够使得 ...

  5. bzoj1478:Sgu282 Isomorphism

    思路:由于题目中是通过改变点的编号来判断两种染色方案是否相同,而染色的确是边,于是考虑如何将点置换转化为边置换. 对于一个有n个点的完全图,其点置换有n!个(即全排列个数),又由于每一个边置换都对应了 ...

  6. 「算法笔记」Polya 定理

    一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...

  7. 【BZOJ 1478】 1478: Sgu282 Isomorphism (置换、burnside引理)

    1478: Sgu282 Isomorphism Description 给 定一个N 个结点的无向完全图( 任意两个结点之间有一条边), 现在你可以用 M 种颜色对这个图的每条边进行染色,每条边必须 ...

  8. 【转】Polya定理

    转自:http://endlesscount.blog.163.com/blog/static/82119787201221324524202/ Polya定理 首先记Sn为有前n个正整数组成的集合, ...

  9. 【群论】polya定理

    对Polya定理的个人认识     我们先来看一道经典题目:     He's Circles(SGU 294)         有一个长度为N的环,上面写着“X”和“E”,问本质不同的环有多少个(不 ...

随机推荐

  1. 四、Zabbix-zabbix agent部署

    1.添加zabbix安装源 rpm -i http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch ...

  2. 二、Zabbix-zabbix server部署-LNMP

    部署Zabbix server主要分为两部分(软件基本都是yum安装,不要问我为什么不用源码,因为没有必须用源码的需求) 一.部署LNMP/LAMP环境,已提供zabbix的界面展示,已经zabbix ...

  3. JAVA获取当前系统时间System.currentTimeMillis()以及获取运行时间

    System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数,Date()其实就是相当于Date(System.currentTimeMi ...

  4. 如何去完成一个html网页

    其实我也是菜鸟一个,不过我还是想说说,昨晚看的视频好回忆回忆. 看到这样一个网页我们要怎么入手,这个就要像庖丁解牛一样,我们要对它的各个位置都要了解,分析出页面的结构,要有一个总体的把握,先把这个页面 ...

  5. BrokenPipeError: [Errno 32] Broken pipe

    运行Pytorch tutorial代码报错:BrokenPipeError: [Errno 32] Broken pipe 源代码地址: Training a classifier (CIFAR10 ...

  6. STM32内核简介

    STM32F407 的内核是cortex-M4   采用的是ARM架构,具体是ARM-V7架构. 而ARM-V7架构分为三个系列: 1>.A系列:面向尖端的基于虚拟内存的操作系统和用户应用: 2 ...

  7. 神经风格转换Neural Style Transfer a review

    原文:http://mp.weixin.qq.com/s/t_jknoYuyAM9fu6CI8OdNw 作者:Yongcheng Jing 等 机器之心编译 风格迁移是近来人工智能领域内的一个热门研究 ...

  8. qthread线程

    一般调用quit()函数之后可以紧接着调用wait()函数确保线程退出.sleep()等让线程休眠的函数不需要调用,因为Qt中线程是事件驱动机制.但是如果是继承的QTHread类,在run()函数中使 ...

  9. git分支管理和工作流规范:不同场景细化和演示

    https://www.iteye.com/blog/qqtalk-2415889 前两篇介绍了 git基本概念 和 具体的规范,本篇针对不同的使用场景做演示. 分支 分支命名 master 分支名称 ...

  10. LOJ#2330 榕树之心 树形dp

    瞎扯 这个题和\(\mathsf{ISIJ2019 Au}\)神仙学弟\(\mathsf{\color{red}c}\mathsf{hangruinian2020}\)争辩了半个多小时. 概括一下就是 ...