poj 1286 Necklace of Beads 题解
【题意】
给定 \(n\) 个空位待填的圆环,每个空位可以填入红、蓝、绿任一颜色的珠子。问不同构的方案数为多少?
题目认为旋转、沿坐标轴翻转后相同的两个方案是同构的。
\(n<24\)
【分析】
比较裸的 Polya 定理
旋转和翻转,以及这两个变换的运算构成一个群 \(G\) 。
而原本的翻转只能沿坐标轴翻转,但我们考虑先将圆环旋转 \(-\theta\) 度的变换 \(rot_{-\theta}\),再沿 \(x\) 轴翻转 \(sym_0\) ,最后再旋转 \(\theta\) 度 \(rot_{\theta}\) ,则等价于圆环沿 \(\theta\) 的这条极径进行了翻转 \(sym_{\theta}\)。即 \(sym_{\theta}=rot_{\theta}\circ sym_{0}\circ sym_{-\theta}\) 。
由于 \(rot_{\theta}, sym_{0}, rot_{-\theta}\in G\), 根据运算的封闭性,\(sym_{\theta}\in G\) 。即群内包括了任意角度的旋转,和任意角度的翻转。
现考虑到旋转角度只有 \(k\cdot {2\pi\over n}, k\in\{0, 1, 2, \cdots, n-1\}\) 时才有意义,翻转角度只有 \(k\cdot {\pi\over n}, k\in\{0, 1, 2, \cdots, n-1\}\) 时才有意义
当旋转角度为 \(k\cdot {2\pi\over n}\) 时,构成置换 \(\left( \begin{matrix} 1&2&3&\cdots &n-k&n-k+1&\cdots &n \\\\ k+1&k+2&k+3&\cdots&n&1&\cdots &k \end{matrix} \right)\),可拆解成 \(\gcd(k, n)\) 个不可拆解的置换
当 \(n\) 为奇数时,翻转角度 \(k\cdot {\pi\over n}\) 使得除了直线上一点,其余每个点与关于直线的对称点构成一个置换,故可拆解成 \(\lceil{n\over 2}\rceil={n+1\over 2}\) 个不可拆解的置换
当 \(n\) 为偶数时,若 \(k\) 为奇数,则翻转角度 \(k\cdot {\pi\over n}\) 使得每个点与关于直线的对称点构成一个置换,可分解为 \({n\over 2}\) 个不可拆解的置换
当 \(n\) 为偶数时,若 \(k\) 为偶数,则翻转角度 \(k\cdot {\pi\over n}\) 使得除线上的两个点,每个点与关于直线的对称点构成一个置换,可分解为 \(({n\over 2}+1)\) 个不可拆解的置换
故根据 Polya 定理:
当 \(n\) 为奇数时,方案数为 \(\displaystyle {1\over 2n}(\sum_{i=0}^{n-1} 3^{\gcd(i, n)} + \sum_{i=0}^{n-1} 3^{n+1\over 2})={1\over 2n}(\sum_{i=0}^{n-1} 3^{\gcd(i, n)} + n\cdot 3^{n+1\over 2})\)
当 \(n\) 为偶数时,方案数为 \(\displaystyle {1\over 2n}(\sum_{i=0}^{n-1} 3^{\gcd(i, n)} + \sum_{i=0}^{n-1}3^{n\over 2}[2\nmid n]+\sum_{i=0}^{n-1}3^{{n\over 2}+1}[2\mid n])={1\over 2n}(\sum_{i=0}^{n-1} 3^{\gcd(i, n)} + 2n\cdot 3^{n\over 2})\)
到这一步已经可以出答案了,不过本人顺着莫比乌斯反演推了推:
\(\displaystyle \sum_{i=0}^{n-1} 3^{\gcd(i, n)}=\sum_{i=1}^n 3^{\gcd(i, n)}=\sum_{d\mid n}3^d\sum_{i=1}^n[\gcd(i, n)=d]=\sum_{d\mid n}3^d\boldsymbol \varphi({n\over d})\)
【代码】
本来是想 Python 直接冲的,猛地发现 POJ 不能交 Python,这里就直接敲了个表,然后 C++ 交上去
phi = [0, 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, 18, 12, 28, 8, 30]
pow3 = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467, 3486784401, 10460353203, 31381059609, 94143178827, 282429536481, 847288609443, 2541865828329, 7625597484987, 22876792454961, 68630377364883, 205891132094649, 617673396283947]
ans = [0]
for i in range(1, 32) :
tmp = 0
for d in range(1, i+1) :
if i%d == 0 :
tmp += 3**d*phi[i//d]
if i&1 :
tmp += i*3**((i+1)//2)
else :
tmp += i*2*3**(i//2)
tmp //= 2*i
ans.append(tmp)
print('ans[]={', end='0')
for i in range(1, 32) :
print(', %d'%ans[i], end='')
print('};')