题意

如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图。

如果两张有色图有相同数量的顶点,而且经过某种顶点编号的重排,能够使得两张图对应的边的颜色是一样的,我们就称这两张有色图是同构的。

对于计算所有顶点数为 \(n\) ,颜色种类不超过 \(m\) 的图,最多有几张是两两不同构的图。

数据范围

\(n \le 53, 1 \le m \le 1000\)

题解

神仙题qwq

我们考虑对于点置换与其对应的边置换的关系:

  1. 对于不处在循环中的点对:

    假设第一个循环长度为 \(l_1\) 第二个循环长度为 \(l_2\) ,那么循环节长度就是 \(\mathrm{lcm}(l_1, l_2)\) 。

    一共有 \(l_1\times l_2\) 对点对,每个点对所处的循环节长度都是一样的,那么循环节个数就是 \(\displaystyle \frac{l_1l_2}{\mathrm{lcm}(l_1, l_2)} = \gcd(l_1, l_2)\) 。

  2. 对于处在循环中的点对:

    设循环长度为 \(l\) ,分奇偶讨论。

    • \(l\) 为奇数,那么循环长度刚好是 \(l\) ,一共有 \(\displaystyle {l \choose2}\) 对点对,那么刚好就有 \(\displaystyle \frac{l - 1}2\) 个循环节。
    • \(l\) 为偶数,上面那种情况之外,还有转 \(\displaystyle \frac l2\) 长度对应的循环节,那么一共有 \(\displaystyle\frac{ {l \choose 2} - \frac l2}{l} + 1 = \frac l2\) 个循环节。

设一开始点置换划分的周期为 \(l_1 \le l_2 \le \cdots \le l_k\) ,其中满足 \(\sum\limits _{i = 1}^{k} l_i = n\) 。

那么循环节的个数其实就是:

\[\sum_{i = 1}^{k} \lfloor \frac{l_i}{2} \rfloor + \sum_{i = 1}^{k} \sum_{j = i + 1}^{k} \gcd(l_i, l_j)
\]

我们显然可以枚举所有 \(l\) 的集合,不难发现这就是整数划分,\(53\) 的划分数并不大。。。

只剩下最后一个问题,就是有多少个长为 \(n\) 的排列对应到 \(l_1 \cdots l_k\) 这个点置换循环。

首先考虑可重排列计数,把 \(n\) 个数分给这些的方案为 \(\displaystyle \frac{n!}{\prod_{i=1}^{k} l_i!}\) 然后对于每个置换 \(i\) 内部是个圆排列,顺序有 \((l_i - 1)!\) 。然后循环的先后顺序是互不影响的,要除掉 \(c_i! (c_i = \sum_{j = 1}^{n}[l_j = i])\) 个。

也就是

\[\frac{n!}{\prod_{i = 1}^{k}l_i \prod_{i = 1}^{k}c_i!}
\]

总结

对于 \(Polya\) 定理,常常要找循环节个数。对于特殊的置换,我们常常可以利用循环长度是一样的性质,然后用总元素 \(/\) 循环长度,得到循环节个数。

代码

#include <bits/stdc++.h>

#define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl using namespace std; template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; } inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
} void File() {
#ifdef zjp_shadow
freopen ("1815.in", "r", stdin);
freopen ("1815.out", "w", stdout);
#endif
} const int N = 65; int n, m, Mod; int cir[N], len, ans = 0; inline int fpm(int x, int power) {
int res = 1;
for (; power; power >>= 1, x = 1ll * x * x % Mod)
if (power & 1) res = 1ll * res * x % Mod;
return res;
} void Dfs(int cur, int rest, int res) {
if (!rest) {
int coef = 1, cnt = 1;
For (i, 1, len) {
if (cir[i] != cir[i - 1]) cnt = 1; else ++ cnt;
coef = 1ll * coef * cnt % Mod * cir[i] % Mod;
}
ans = (ans + 1ll * fpm(m, res) * fpm(coef, Mod - 2)) % Mod; return;
}
For (i, cur, rest) {
int tmp = i / 2; For (j, 1, len) tmp += __gcd(i, cir[j]);
cir[++ len] = i; Dfs(i, rest - i, res + tmp); -- len;
}
} int main () { File(); n = read(); m = read(); Mod = read(); Dfs(1, n, 0); printf ("%d\n", ans); return 0; }

BZOJ 1815: [Shoi2006]color 有色图(Polya定理)的更多相关文章

  1. BZOJ 1815: [Shoi2006]color 有色图 [Polya DFS 重复合并]

    传送门 题意: 染色图是无向完全图,且每条边可被染成k种颜色中的一种.两个染色图是同构的,当且仅当可以改变一个图的顶点的编号,使得两个染色图完全相同.问N个顶点,k种颜色,本质不同的染色图个数(模质数 ...

  2. bzoj 1815: [Shoi2006]color 有色图 置换群

    1815: [Shoi2006]color 有色图 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 136  Solved: 50[Submit][Stat ...

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

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

  4. BZOJ1815: [Shoi2006]color 有色图

    BZOJ1815: [Shoi2006]color 有色图 Description Input 输入三个整数N,M,P 1< = N <= 53 1< = M < = 1000 ...

  5. [SHOI2006]color 有色图[群论、组合计数]

    题意 用 \(m\) 种颜色,给 \(n\) 个点的无向完全图的 \(\frac{n(n-1)}{2}\) 条边染色,两种方案相同当且仅当一种方案交换一些点的编号后可以变成另一种方案.问有多少本质不同 ...

  6. POJ2154 Color 【Polya定理 + 欧拉函数】

    题目 Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). ...

  7. poj 2154 Color【polya定理+欧拉函数】

    根据polya定理,答案应该是 \[ \frac{1}{n}\sum_{i=1}^{n}n^{gcd(i,n)} \] 但是这个显然不能直接求,因为n是1e9级别的,所以推一波式子: \[ \frac ...

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

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

  9. 洛谷 P4128: bzoj 1815: [SHOI2006]有色图

    题目传送门:洛谷 P4128. 计数好题,原来是 13 年前就出现了经典套路啊.这题在当年应该很难吧. 题意简述: \(n\) 个点的完全图,点没有颜色,边有 \(m\) 种颜色,问本质不同的图的数量 ...

随机推荐

  1. 从零开始学安全(四十一)●初识Wireshark

    wireshark:Beyond Compare是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与 ...

  2. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  3. Java基础小知识笔记

    1. Integer转进制的一个类2. toBinaryString,toOctalString,toHexString.(转为二进制,八进制,十六进制的方法)3. 如果·数据的大小没有超过byte/ ...

  4. vuex最简单、最直白、最全的入门文档

    前言 我们经常用element-ui做后台管理系统,经常会遇到父组件给子组件传递数据,下面一个简单的例子,点击按钮,把弹框显示变量数据通过子组件的props属性传递,子组件通过$emit事件监听把数据 ...

  5. 给萌新的Flexbox简易入门教程

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.sitepoint.com/flexbox-css-flexible-bo ...

  6. 在项目管理中如何保持专注,分享一个轻量的时间管理工具【Flow Mac版 - 追踪你在Mac上的时间消耗】

    在项目管理和团队作业中,经常面临的问题就是时间管理和优先级管理发生问题,项目被delay,团队工作延后,无法达到预期目标. 这个仿佛是每个人都会遇到的问题,特别是现在这么多的内容软件来分散我们的注意力 ...

  7. [20190418]exclusive latch spin count.txt

    [20190418]exclusive latch spin count.txt--//昨天测试"process allocation" latch,主要这个latch与其它拴锁s ...

  8. VirtualBox Network Config

    Sharing Host VPN with VirtualBox guest After looking for this solution everywhere, I finally found a ...

  9. Linux学习历程——Centos 7 find 命令

    一.命令介绍 find 命令用于按照指定条件来查找文件. 一些比较常用参数如下表 参数 作用 -name 匹配名称 -perm 匹配权限mode为完全匹配( –mode包含即可) -user 匹配所有 ...

  10. 数据结构学习之字符串匹配算法(BF||KMP)

    数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 ​ 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 ​ 编写出BF暴力匹配.KM ...