bzoj1478:Sgu282 Isomorphism
思路:由于题目中是通过改变点的编号来判断两种染色方案是否相同,而染色的确是边,于是考虑如何将点置换转化为边置换。
对于一个有n个点的完全图,其点置换有n!个(即全排列个数),又由于每一个边置换都对应了一个点置换(因为是改变点的编号才得到的边置换),因而边置换也是n!个,也就是说已经确定了Polya定理中的分母,考虑分子怎么求。
对于一个点置换,会形成一些循环,而这些循环所对应的边置换也是一个循环,同时,这些点循环之间的边也会形成一个循环,边置换中的总循环数就取决于点置换循环中对应的边置换循环和点置换循环间对应的边置换循环。
首先考虑来求点置换循环间对应的边循环数,其所对应边置换一个循环的长度是lcm(Li,Lj)(这里和下面的Li,Lj都表示点循环的长度),因为可以看成是一个长为Li的齿轮和长为Lj的齿轮,初始时有两个涂有颜色的槽嵌在一起,然后问经过多少个槽这两个点再次嵌在一起,很显然是lcm(Li,Lj),然后一共有Li*Lj条边,且循环间无交集,因此一共就是Li*Lj/lcm(Li,Lj)=gcd(Li,Lj)。
接着考虑如何来求点置换循环内部对应的边置换循环数,分奇环和偶环考虑,首先对于奇环显然对应每个边置换长度为Li,因为考虑一个环然后一条边连接任意两个点,然后每一次边连接的两个点都跳到下一个点,过了n次相当于又回到了一个起点,那么这就是一个边置换循环,那有没有可能更短呢?没有,如果令那条边连接的两个点为点A和点B,那么更短只可能是点A走到点B同时点B又走到点A,那么此时A,B恰好经过一个点置换环的长度,且A,B经过距离相等,那这就不再是一个奇环而是一个偶环了,所以假设不成立,因而n一定是最短的也是边置换循环的长度,然后一共就Li*(Li-1)/2条边,因此答案就是(li-1)/2条边。而对于偶环边置换长度同样也令它为Li,但依照前面去推就有个Bug,就是当选的边恰好是该环一条经过点的对称轴时,那么此时边置换的长度就是Li/2而不是Li,这样就相当于多算了Li/2条边,于是用总的Li*(Li-1)/2条边-Li/2条边作为总边数,最后答案加1即可,此时答案即Li/2条边,统一一下即:点置换循环内对应的边置换循环数即Li/2条边。
那么这样,m的指数也已经出来了,那这样总不能一个一个去累加吧,因为总数高达n!,但可以发现指数只和Li和Lj有关,而所有的Li之和就恰好是n,于是可以把Li相同的一起讨论,这样即n的拆分,而n的拆分并不大,只有30多万多种,这样就只需计算n的一种拆分再去乘以这种拆分下的有多少种即可,而这个多少种是有公式的,首先定义Bi表示n的拆分(即L集合)中等于i的个数,那么方案数就是n!/(L1*L2*...*Lk*B1!*B2!*B3!*...*Bk!)(蒟蒻并不知道这个公式怎么证明,但这好像是一个定理,而且组合数学应用本书上都好像是直接给出并没有证明QAQ)然后用逆元什么的搞一搞就好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; int n,m,p,top,ans;
int l[100],frac[100],b[100]; int power(int a,int k,int p){
if (k==0) return 1;
if (k==1) return a%p;
int x=power(a,k/2,p),ans=1ll*x*x%p;
if (k&1) ans=1ll*ans*a%p;
return ans;
} int calc(){
int ans=frac[n],div=1;
for (int i=1;i<=top;i++) div=1ll*div*l[i]%p;
for (int i=1;i<100;i++) if (b[i]) div=1ll*div*frac[b[i]]%p;
return 1ll*ans*power(div,p-2,p)%p;
} int gcd(int a,int b){return b==0?a:gcd(b,a%b);} int solve(){
int ans=0;
for (int i=1;i<=top;i++) ans+=l[i]/2;
for (int i=1;i<top;i++)
for (int j=i+1;j<=top;j++)
ans+=gcd(l[i],l[j]);
return ans;
} void dfs(int remain,int last){
if (!remain){
ans=(ans+1ll*calc()*power(m,solve(),p)%p)%p;
return;
}
for (int i=min(remain,last);i;i--)
l[++top]=i,b[i]++,dfs(remain-i,i),top--,b[i]--;
} int main(){
scanf("%d%d%d",&n,&m,&p);frac[0]=1;
for (int i=1;i<=n;i++) frac[i]=1ll*frac[i-1]*i%p;
dfs(n,n);ans=1ll*ans*power(frac[n],p-2,p)%p;
printf("%d\n",ans);
return 0;
}
UPD:一年以后来复习Polya的时候突然发现上面那个式子就是共轭类的个数的式子。。。。。。
假设我们已经得到了这些Li,按Li排序然后从左往右排成一个长为n的排列,一共有n!种排列,但显然有重复。
对于一个循环内,例如一个点循环的长度为k,例如(a1,a2,a3...ak),它循环左移若干位后得到的点循环是一样的,一共有k种,然后每一个点循环都会被多算,也就是要除以所有的Li。
然后考虑长度相同的点循环,例如一个点循环的长度为k,这样的点循环有Bk个,显然(a1,a2)(a3,a4)与(a3,a4)(a1,a2)是一样的,也就是说会被多算Bk!,然后就要除以所有的Bk!
bzoj1478:Sgu282 Isomorphism的更多相关文章
- 【BZOJ1478】Sgu282 Isomorphism Pólya定理神题
[BZOJ1478]Sgu282 Isomorphism 题意:用$m$种颜色去染一张$n$个点的完全图,如果一个图可以通过节点重新标号变成另外一个图,则称这两个图是相同的.问不同的染色方案数.答案对 ...
- [BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理
分析 三倍经验题,本文以[BZOJ1478][SGU282]Isomorphism为例展开叙述,主体思路与另外两题大(wan)致(quan)相(yi)同(zhi). 这可能是博主目前写过最长也是最认真 ...
- BZOJ1478 Sgu282 Isomorphism
Problem A: Sgu282 Isomorphism Time Limit: 15 Sec Memory Limit: 64 MBSubmit: 172 Solved: 88[Submit] ...
- 【BZOJ 1478】 1478: Sgu282 Isomorphism (置换、burnside引理)
1478: Sgu282 Isomorphism Description 给 定一个N 个结点的无向完全图( 任意两个结点之间有一条边), 现在你可以用 M 种颜色对这个图的每条边进行染色,每条边必须 ...
- bzoj 1478: Sgu282 Isomorphism && 1815: [Shoi2006]color 有色图【dfs+polya定理】
参考 https://wenku.baidu.com/view/fee9e9b9bceb19e8b8f6ba7a.html?from=search### 的最后一道例题 首先无向完全图是个若干点的置换 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 「算法笔记」Polya 定理
一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...
- Category Theory: 01 One Structured Family of Structures
Category Theory: 01 One Structured Family of Structures 这次看来要放弃了.看了大概三分之一.似乎不能够让注意力集中了.先更新吧. 群的定义 \( ...
- 【PTA】浙江大学数据结构慕课 课后编程作业 03-树1 树的同构
题目内容 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右 ...
随机推荐
- 【Java基础】Java接口的总结
什么是接口 接口和抽象类很相似,也是一种抽象的概念,用Interface关键字来修饰.那有了抽象类为啥还要有个接口呢,既然都是抽象的,要一个不就可以了吗?其实不是这样的,抽象类是对一类事物共性的一种抽 ...
- POJ1182食物链 (并查集)
第一反应就是和那个搞基的虫子的题很像(poj2492 http://www.cnblogs.com/wenruo/p/4658874.html),不过是把种类从2变成了3. 错在很白痴的地方,卡了好久 ...
- 操作系统课堂笔记(2)操作系统的硬件环境之I/O技术和时钟
I/O技术 1.程序控制I/O技术 有处理器提供相关的IO指令来实现的.主要缺陷是,处理器必须关注IO处理单元的状态,因而它会耗费大量的时间轮询以获得这个信息,这严重降低了系统性能. 2.中断驱动I/ ...
- Android获取ip地址
原文:http://www.cnblogs.com/android100/p/Android-get-ip.html 1.使用WIFI 首先设置用户权限 <uses-permission and ...
- 10409 - Die Game
Problem G: Die Game Life is not easy. Sometimes it is beyond your control. Now, as contestants of AC ...
- [React] React Fundamentals: State Basics
State is used for properties on a component that will change, versus static properties that are pass ...
- 用Python和FFmpeg查找大码率的视频文件
用Python和FFmpeg查找大码率的视频文件 本文使用Python2.7, 这个工作分两步 遍历目录下的视频文件 用ffprobe获取是视频文件的码率信息 用ffprobe 获取json格式的视频 ...
- Design Of A Modern Cache
http://highscalability.com/blog/2016/1/25/design-of-a-modern-cache.html MONDAY, JANUARY 25, 2016 AT ...
- 通过blktrace, debugfs分析磁盘IO
前几天微博上有同学问我磁盘util达到了100%时程序性能下降的问题,由于信息实在有限,我也没有办法帮太大的忙,这篇blog只是想给他列一下在磁盘util很高的时候如何通过blktrace+debug ...
- iostat详解
http://www.penglixun.com/tech/system/use_iostat_analyse_linux_disks.html