[SHOI2006]color 有色图[群论、组合计数]
题意
用 \(m\) 种颜色,给 \(n\) 个点的无向完全图的 \(\frac{n(n-1)}{2}\) 条边染色,两种方案相同当且仅当一种方案交换一些点的编号后可以变成另一种方案。问有多少本质不同的染色方案。
\(n\le 53, m\le 1000, n<mod\le 10^9\) 且 \(mod\) 为质数。
分析
- 考虑 \(Polya\) 定理。
- 假设已经枚举了一个点置换(对应唯一一种边置换),能否快速求出对应边的置换的循环个数?
- 对于两个点的循环(设长度分别为 \(l_1,l_2\)),它们之间的边构成了 \(\frac{l_1l_2}{lcm(l_1,l_2)}=gcd(l_1,l_2)\) 个边的循环。
- 对于一个点循环内部的边:假设初始在序列上选定的两个点的位置相差了 \(x\) ,在右端点转回序列左端后差值会变成 \(n-x\) 。可以得到,当且仅当 \(2x=n\) 时,循环长度为 \(\frac{n}{2}\)(无向图) ,其余时刻为 \(n\) 。所以当 \(n\) 为偶数时的边循环个数还要加 1。由于总边数为 \(\frac{n(n-1)}{2}\) ,所以边循环个数总可以写成 \(\lfloor\frac{n}{2}\rfloor\) 的形式。
- 那么对于一种点置换,假设其所有循环满足 \(l_1\le l_2\le \cdots\le l_k\) ,这样的置换个数为 \(\frac{n!}{l_1l_2\cdots l_kS_1!S_2!\cdots S_{max}!}\) ,其中 \(S_i\) 表示长度为 \(i\) 的循环个数。为什么是 \(l_i\) 而不是 \(l_i!\) 的原因是每次我们找 \(l_i\) 个位置作为一个循环之后,他们都连了一条指向其他位置的边,构成了一个环。环排列的个数是 \(\frac{n!}{n}=(n-1)!\) 。
- 综上,对于一种点置换,对应边置换的循环个数为 \(\sum_{i=1}^k\lfloor\frac{l_i}{2}\rfloor+\sum_{i=1}^{k-1}\sum_{j=i+1}^kgcd(l_i,l_j)\) 。
- 由于 \(n\le 53\) ,拆分的方案数在一个可接受的范围内。所以爆搜循环的拆分即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define pb push_back
#define re(x) memset(x, 0, sizeof x)
inline int gi() {
int x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
return x * f;
}
template <typename T> inline bool Max(T &a, T b){return a < b ? a = b, 1 : 0;}
template <typename T> inline bool Min(T &a, T b){return a > b ? a = b, 1 : 0;}
const int N = 60;
int n, m, mod;
LL fac[N], invfac[N], inv[N], ans;
int g[N][N], stk[N], num[N];
LL Pow(LL a, LL b) {
LL res = 1ll;
for(; b; b >>= 1, a = a * a % mod) if(b & 1) res = res * a % mod;
return res;
}
void add(LL &a, LL b) {
a += b;
if(a >= mod) a -= mod;
}
void solve( int tp) {
re(num);
rep(i, 1, tp) num[stk[i]]++;
LL cnt = fac[n];
rep(i, 1, tp) cnt = cnt * inv[stk[i]] % mod;
rep(i, 1, n) cnt = cnt * invfac[num[i]] % mod;
LL c = 0;
rep(i, 1, tp) c = (c + stk[i] / 2) % (mod - 1);
rep(i, 1, tp - 1)
rep(j, i + 1, tp) c = (c + g[stk[i]][stk[j]]) % (mod - 1);
add(ans, cnt * Pow(m, c) % mod);
}
void dfs(int dep, int rest, int lst) {
if(!rest) {
solve(dep - 1);
return;
}
for(int i = lst; i <= rest; ++i) stk[dep] = i, dfs(dep + 1, rest - i, i);
}
int gcd(int a, int b) {
return !b ? a : gcd(b, a % b);
}
int main() {
n = gi(), m = gi(), mod = gi();
rep(i, 0, n)
rep(j, 0, n) g[i][j] = gcd(i, j);
inv[1] = fac[0] = invfac[0] = 1;
rep(i, 1, n) {
if(i ^ 1) inv[i] = (LL) (mod - mod / i) *inv[mod % i] % mod;
fac[i] = (LL) fac[i - 1] * i % mod;
invfac[i] = (LL) invfac[i - 1] * inv[i] % mod;
}
inv[0] = 1;
dfs(1, n, 1);
printf("%lld\n", ans * invfac[n] % mod);
return 0;
}
[SHOI2006]color 有色图[群论、组合计数]的更多相关文章
- bzoj 1815: [Shoi2006]color 有色图 置换群
1815: [Shoi2006]color 有色图 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 136 Solved: 50[Submit][Stat ...
- BZOJ1815: [Shoi2006]color 有色图
BZOJ1815: [Shoi2006]color 有色图 Description Input 输入三个整数N,M,P 1< = N <= 53 1< = M < = 1000 ...
- BZOJ 1815: [Shoi2006]color 有色图(Polya定理)
题意 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图. 如果两张有色图有相同数量的顶点,而且经过某种顶点编号的重排,能够使得 ...
- BZOJ 1815: [Shoi2006]color 有色图 [Polya DFS 重复合并]
传送门 题意: 染色图是无向完全图,且每条边可被染成k种颜色中的一种.两个染色图是同构的,当且仅当可以改变一个图的顶点的编号,使得两个染色图完全相同.问N个顶点,k种颜色,本质不同的染色图个数(模质数 ...
- bzoj 1478: Sgu282 Isomorphism && 1815: [Shoi2006]color 有色图【dfs+polya定理】
参考 https://wenku.baidu.com/view/fee9e9b9bceb19e8b8f6ba7a.html?from=search### 的最后一道例题 首先无向完全图是个若干点的置换 ...
- bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)
黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]
4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]
4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...
- 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)
[HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...
随机推荐
- Android为TV端助力 handler ,message消息发送方式
1.Message msg = Message.obtain(mainHandler) msg.obj=obj;//添加你需要附加上去的内容 msg.what = what;//what消息处理的类 ...
- WPF:解决DataGrid横向滚动条无法显示的问题
DataGrid的最后一列的宽度设置为“Width=”auto””即可. 如果显示指定长度或者设置为“*”,那么不管怎么拖动列头,或者不管行里面的内容有没有超过DataGrid的显示区域,DataGr ...
- create table 使用select查询语句创建表的方法分享
转自:http://www.maomao365.com/?p=6642 摘要:下文讲述使用select查询语句建立新的数据表的方法分享 ---1 mysql create table `新数据表名` ...
- JQuery实现全选、全不选和反选功能
看重点就行了,最后面给一个网页完整的代码 代码实例: function selectStu() { $.ajax("StuList",{ type:"post" ...
- DAC连接
专用管理员连接是一种特殊的SQL Server服务器诊断性质的连接,用于在正常或者说标准连接形式无法连接SQL Server服务器的情况下连接到服务器进行服务器性能或者错误诊断.DAC同样支持安全加密 ...
- Powershell批量安装SNMP服务
我要给node5-8的节点都安装snmp服务 如果不知道要安装的服务的名字,用get-windowsfeature 能显示出来所有的名字 Invoke-Command -ComputerName no ...
- cve-2017-11882 poc分析
目录 CVE-2017-11882 poc分析 0x00 工具&实验环境 0x01 分析行为 第一步:观察poc行为 第二步:找出计算器被弹出的地方 0x02 调试定位漏洞触发点 0x03 分 ...
- PHP中cURL的应用
这里是慕课网上讲cURL 的一张图,觉得吧这个过程说的很清楚,因此就不错了. 1, 打开一个网页,下载网页内容 <?php $curl = curl_init("http://www. ...
- ASP.NET -- WebForm -- HttpResponse 类的方法和属性
ASP.NET -- WebForm -- HttpResponse 类的方法和属性 1. HttpResponse 类的方法 (1) AddCacheDependency: 将一组缓存依赖项与响应关 ...
- March 03rd, 2018 Week 9th Saturday
No cross, no crown. 不经历风雨,怎能见彩虹. Sometimes you can see a beautiful rainbow high in the sky without h ...