(每日一题)P4128 [SHOI2006] 有色图(文末有色图!)(Polya定理)(超级详细,清晰易懂)

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.13 群论

嘿嘿嘿,本题题名为 有涩图

文末有色图哦!

P4128 [SHOI2006] 有色图

Weblink

https://www.luogu.com.cn/problem/P4128

Problem
在这里插入图片描述
Solution

题目中两个色图相同,当且仅当 n ! n! n! 的点的排列有相同的边的颜色,也就求本质不同的染色方案数。显然要用Burnside引理或者Polya定理解决。

我们知道任意一种置换都可以表示为若干个不相交的循环置换的乘积,即每个循环置换包含若干个点,总点数为 n n n 。由于一共只有 n ≤ 53 n\le 53 n53 个点,我们可以直接暴力 d f s dfs dfs 求一下 n n n 的拆分数,即将 n n n 个点拆分为若干个互不相交的循环置换,假设每个循环置换包含的点的个数为 a i a_i ai,一共 t t t 个循环置换,则 ∑ i = 1 t a i = n \sum\limits_{i=1}^{t}a_i=n i=1tai=n

如果我们知道 n n n 个点拆分为若干个循环置换的方案数,根据乘法原理,再乘上用Polya定理计算出来的每个被拆出来的循环置换的本质不同的方案数既是答案。

那么首先计算 n n n 的拆分数的方案数: 显然 n n n 个点任意排列的方案数为 n ! n! n! 。即方案数最多为 n ! n! n! ,我们再去掉多算的方案数即可。

假设我们拆分为 t t t 个循环: a 1 , a 2 , a 3 ⋯   , a t a_1,a_2,a_3\cdots,a_t a1,a2,a3,at a i a_i ai 表示第 i i i 个循环包含的点的个数)。

首先,我们计算本质不同的时候每一个循环置换在 n n n 个点中选择的起点不管谁都是同一种方案数(循环置换嘛,起点是谁最后都是一个圈,可以理解为是一个圆排列,旋转同构),所以要要去掉这些多算的方案数,即除掉所有的起点个数的乘积的方案数: ∏ i = 1 t 1 a i \prod\limits_{i=1}^t \dfrac 1{a_i} i=1tai1

其次,如果两个循环置换的点的个数完全相同的话,他们两个的顺序怎么摆放都是同一种方案,即我们统计一下每一个循环置换的点数为 x x x 的循环置换个数: c n t x cnt_x cntx,总方案数需要去掉这些方案数,即除掉所有相同循环置换点数的个数之间的排列: ∏ x 1 c n t x ! \prod\limits_{x}\dfrac 1 {cnt_x!} xcntx!1

综上所诉,将 n n n 个点拆分为若干个循环置换的总方案数为

r e s = n ! ∏ i = 1 t a i ∏ x c n t x ! res=\dfrac {n!}{\prod\limits_{i=1}^t {a_i}\prod\limits_{x}{cnt_x!}} res=i=1taixcntx!n!

然后再来分析循环置换本身染色的方案数:

根据Polya定理,对于一个置换 f f f C ( f ) = k m ( f ) C(f)=k^{m(f)} C(f)=km(f),其中 k k k 为颜色数, m ( f ) m(f) m(f) f f f 的循环节。等价类个数(方案数)等于所有置换 f f f k m ( f ) k^{m(f)} km(f) 的平均数。

方案数为:

N = ∑ i = 0 ∣ G ∣ k m ( f i ) ∣ G ∣ N=\cfrac{\sum_{i=0}^{|G|}k^{m(f_i)}}{|G|} N=Gi=0Gkm(fi)

显然我们一共有 n ! n! n! 种置换(拆分为 n ! n! n! 种循环置换),即 ∣ G ∣ = n ! |G|=n! G=n!

N = ∑ i = 0 n ! k m ( f i ) n ! N=\cfrac{\sum_{i=0}^{n!}k^{m(f_i)}}{n!} N=n!i=0n!km(fi)

也就是说我们只需要计算一下我们拆分出来的每一个循环置换的不动点的个数 m ( f i ) m(f_i) m(fi) 即可。

我们拆分出 t t t 个循环: a 1 , a 2 , a 3 ⋯   , a t a_1,a_2,a_3\cdots,a_t a1,a2,a3,at a i a_i ai 表示第 i i i 个循环包含的点的个数),假设分别为点集 ( A 1 , A 2 , ⋯   , A a 1 ) , ( B 1 , B 2 , ⋯   , B a 2 ) , ⋯ (A_1,A_2,\cdots,A_{a_1}),(B_1,B_2,\cdots,B_{a_2}),\cdots (A1,A2,,Aa1),(B1,B2,,Ba2),

对于在同一个循环内部的点:

显然就是一个旋转同构,即每一个循环置换中的不动点个数为 ⌊ a i 2 ⌋ \lfloor \dfrac {a_i} 2 \rfloor 2ai 个。

对于在不同循环内部的点:

显然就是一个对称同构,即每一个循环置换中的不动点个数为 ∑ 1 ≤ i < j ≤ m gcd ⁡ ( a i , a j ) \sum\limits_{1\le i<j\le m} \gcd(a_i,a_j) 1i<jmgcd(ai,aj)

综上所述,答案 a n s ans ans 为:

a n s =   r e s × N =   1 ∣ G ∣ × n ! ∏ i = 1 t a i ∏ x c n t x ! k ∑ i = 1 m ⌊ a i 2 ⌋ + ∑ 1 ≤ i < j ≤ m gcd ⁡ ( a i , a j ) =   k ∑ i = 1 m ⌊ a i 2 ⌋ + ∑ 1 ≤ i < j ≤ m gcd ⁡ ( a i , a j ) ∏ i = 1 t a i ∏ x c n t x ! \begin{aligned}ans= &\ res\times N \\ =&\ \displaystyle\cfrac{1}{|G|}\times \dfrac{n!}{\prod\limits_{i=1}^t {a_i}\prod\limits_{x}{cnt_x!}} k^{\sum\limits_{i=1}^m\lfloor \cfrac {a_i} 2 \rfloor+\sum\limits_{1\le i<j\le m} \gcd(a_i,a_j)}\\=\ & \displaystyle\dfrac{k^{\sum\limits_{i=1}^m\lfloor \cfrac {a_i} 2 \rfloor+\sum\limits_{1\le i<j\le m} \gcd(a_i,a_j)}}{\prod\limits_{i=1}^t {a_i}\prod\limits_{x}{cnt_x!}}\end{aligned} ans===  res×N G1×i=1taixcntx!n!ki=1m2ai+1i<jmgcd(ai,aj)i=1taixcntx!ki=1m2ai+1i<jmgcd(ai,aj)

注意不要手贱把 k u p k^{up} kup 里的 u p up up 膜掉 m o d mod mod 了,这个最后可以要当作次幂用的啊,应该膜 m o d − 1 mod - 1 mod1 !!!

Code

// Problem: P4128 [SHOI2006] 有色图
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4128
// Memory Limit: 125 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;
#define int long long
const int N = 5e5 + 7;

int n, m, t, mod, cnt, k;
int a[N];
int fact[N], infact[N], inv[N];
int ans;

int qpow(int a, int b)
{
	int res = 1;
	while(b) {
		if(b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

void init(int n)
{
	fact[0] = inv[1] = infact[0] = 1;
	for(int i = 2; i <= n; ++ i)
		inv[i] = inv[mod % i] * (mod - mod / i) % mod;
	for(int i = 1; i <= n; ++ i) {
		fact[i] = fact[i - 1] * i % mod;
		infact[i] = infact[i - 1] * inv[i] % mod;
	}
}

int up, down = 1;

void dfs(int now, int maxx, int cnt)
{
	if(now == 0) {
		ans = (ans + qpow(k, up) * down) % mod;
		return ;
	}
	int UP = up, DOWN = down;
	for(int i = 1; i <= maxx; ++ i) {
		a[ ++ m] = i;//a[m] = i 就是公式里的 a[i]
		up = (UP + i / 2) % (mod - 1);
		for(int j = 1; j < m; ++ j)
			up += __gcd(a[j], i) % (mod - 1);
		down = (DOWN * inv[i]) % mod;
		if(i == a[m - 1]) {//is same
			down = (down * inv[cnt + 1]) % mod;
			dfs(now - i, min(now - i, i), cnt + 1);
		}
		else dfs(now - i, min(now - i, i), 1);
		m -- ;
	}
}

signed main()
{
	cin >> n >> k >> mod;
	down = 1;
	init(N - 7);
	dfs(n, n, 0);
	cout << ans << endl;
	return 0;

}

你们要的色图:

在这里插入图片描述

已标记关键词 清除标记
相关推荐
<p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <br /> </p> <p> <br /> </p> <p> 本课程内容包含讲解<span>解读Nginx的基础知识,</span><span>解读Nginx的核心知识、带领学员进行</span>高并发环境下的Nginx性能优化实战,让学生能够快速将所学融合到企业应用中。 </p> <p> <br /> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><br /> </b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"><span id="__kindeditor_bookmark_start_21__"></span></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程永久有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a>,播放页面右侧点击课件进行资料打包下载 </p> <p> <br /> </p> <p> <br /> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页