思路:由于题目中是通过改变点的编号来判断两种染色方案是否相同,而染色的确是边,于是考虑如何将点置换转化为边置换。

对于一个有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的更多相关文章

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

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

  2. [BZOJ1478&1488&1815][SGU282]Isomorphism:Polya定理

    分析 三倍经验题,本文以[BZOJ1478][SGU282]Isomorphism为例展开叙述,主体思路与另外两题大(wan)致(quan)相(yi)同(zhi). 这可能是博主目前写过最长也是最认真 ...

  3. BZOJ1478 Sgu282 Isomorphism

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

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

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

  5. bzoj 1478: Sgu282 Isomorphism && 1815: [Shoi2006]color 有色图【dfs+polya定理】

    参考 https://wenku.baidu.com/view/fee9e9b9bceb19e8b8f6ba7a.html?from=search### 的最后一道例题 首先无向完全图是个若干点的置换 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. 「算法笔记」Polya 定理

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

  8. Category Theory: 01 One Structured Family of Structures

    Category Theory: 01 One Structured Family of Structures 这次看来要放弃了.看了大概三分之一.似乎不能够让注意力集中了.先更新吧. 群的定义 \( ...

  9. 【PTA】浙江大学数据结构慕课 课后编程作业 03-树1 树的同构

    题目内容 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右 ...

随机推荐

  1. HDU4737 - A Bit Fun(线段树)

    题目大意 给你一个数组a,定义f(i,j)=ai|ai+1|ai+2|⋯|aj ,|为or运算,求满足f(i,j)<m的二元组个数,N≤105,m≤230 题解 枚举起点i,然后找出最靠右的k, ...

  2. 迷宫 (BFS)

    <挑战程序设计> P34 第一次使用pair 1.头文件:<utility>2.成员:mypair.first, mypair.second3.运算符:<.>.&l ...

  3. nslookup、arp、netstat、traceroute

    nslookup 主要用于测试DNS服务器是否正常工作,除此之外,还可以对域名和IP地址进行查询. [root@weekend110 ~]# nslookup> www.guet.edu.cn ...

  4. iOS网络编程(三) 异步加载及缓存图片---->SDWebImage

    @SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. @SDWebImage的导入1.https:// ...

  5. linux定时器用法

    linux定时器  原文出自http://www.cnblogs.com/processakai/archive/2012/04/11/2442294.html 今天看书看到了关于alarm的一些用法 ...

  6. vmwear 及docker

    1.安装vmwear,开启cpu虚拟化 2.http://jingyan.baidu.com/article/eae0782787b4c01fec548535.html 3.docker

  7. 清理Win8.1更新冗余的批处理代码

    以下为批处理文件内容,复制到文本文件,另存为.bat文件,以管理员方式运行即可. @echo off title 清理Win8.1更新冗余 color 2e echo 提示:本程序可能需要以管理员方式 ...

  8. 【转】C++中了类继承和调用父类的构造函数方法

    构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需 ...

  9. OpenCV2马拉松第22圈——Hough变换直线检測原理与实现

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/27220445 收入囊中 Hough变换 概率Ho ...

  10. Highcharts简介

    最近要做一个油田油压或温度数据的监控软件,数据会秒级写到数据库中,界面上需要动态展示数据跟随时间变化. 在网上找了很多js插件,希望能够即时高效的展示数据,最终确定了使用Highcharts插件. H ...