【模板】Polya 定理/Burnside 引理

Polya 定理

给定一个\(n\)个点,\(n\)条边的环,有\(n\)种颜色,给每个顶点染色,问有多少种本质不同的染色方案,答案对\(10^9+7\)取模

注意本题的本质不同,定义为:只需要不能通过旋转与别的染色方案相同

一种染色方案可以看做先染了前\(d\)个位置,然后将这一段复制\(\frac{n}{d}\)次拼接而成,其中\(d|n\)。我们称这个\(d\)为一种染色方案的周期(这里默认是最小正周期)。

对于一个周期(循环个数)为\(d\)的染色方案,将它旋转\(d\)次会得到\(d\)个看起来不同但本质相同的染色方案。

\(f(x)\)表示周期为\(x\)的看上去不同的方案数。枚举周期\(d\),那么每一种周期的方案就多算\(d\)次,因此\(ans=\sum\limits_{d|n}\dfrac{f(d)}{d}\)

\(f(x)\)不容易计算,但是我们知道:对于\(n\)的所有约数\(d\),将\(f(d)\)求和就会得到总方案数\(m^n\),即

\[m^n=\sum\limits_{d|n}f(d) \]

莫比乌斯反演得

\[f(x)=\sum\limits_{d|x}\mu(\frac{n}{d})m^d \]

代入第一个式子得到

\[ans=\sum\limits_{d|n}\frac{1}{d}\sum\limits_{k|d}\mu(\frac{d}{k})m^k \]

\[=\sum\limits_{d|n}\frac{d}{n}\sum\limits_{k|\frac{n}{d}}\mu(\frac{n}{dk})m^k \]

\[=\frac{1}{n}\sum\limits_{d|n}d\sum\limits_{k|\frac{n}{d}}\mu(\frac{n}{dk})m^k \]

\[=\frac{1}{n}\sum\limits_{k|n}m^k\sum\limits_{d|\frac{n}{k}}d\mu(\frac{n}{dk}) \]

\[=\frac{1}{n}\sum\limits_{k|n}m^k\varphi(n/k) \]

上面设颜色的数量为\(m\)是为了避免混淆,本题中\(m=n\)

Code

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;

int t, n, m;

unordered_map < int, int > fphi;

int read()
{
	int x = 0, fl = 1; char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = x * 10ll + ch - '0'; ch = getchar();}
	return x * fl;
}

int qpow(int base, int pw)
{
	int s = 1;
	while (pw)
	{
		if (pw & 1) s = 1ll * s * base % mod;
		base = 1ll * base * base % mod;
		pw >>= 1;
	}
	return s;
}

int phi(int x)
{
	if (fphi[x]) return fphi[x];
	int t = x, y = x;
	for (int i = 2; i <= m; i ++ )
	{
		if ((x % i) == 0)
		{
			t = t / i * (i - 1);
			while ((x % i) == 0) x /= i;
		}
	}
	if (x > 1) t = t / x * (x - 1);
	return fphi[y] = t;
}

int main()
{
	t = read();
	while (t -- )
	{
		n = read(), m = (int)(sqrt(n));
		int res = 0;
		for (int k = 1; k <= m; k ++ )
		{
			if (n % k) continue;
			res = (res + 1ll * qpow(n, k) * phi(n / k) % mod) % mod;
			if (k * k != n) res = (res + 1ll * qpow(n, n / k) * phi(k) % mod) % mod;
		}
		res = 1ll * res * qpow(n, mod - 2) % mod;
		printf("%d\n", res);
	}
	return 0;
}

Burnside 引理

本质不同的方案数为在每个置换下稳定不动的方案的总和(不动点数目之和)除以总置换数。

注意必须要满足群存在逆元、单位元,且具有封闭性。

posted @ 2021-03-26 14:30  andysj  阅读(91)  评论(0编辑  收藏  举报