链接
https://odzkskevi.qnssl.com/f22f039868cd9df68542406de3a54dd1?v=1537808096
定理介绍
Burnside引理
对于一个置换 f f f,若一个着色方案 s s s经过置换后不变,则 s s s是 f f f的一个不动点,将 f f f的不动点的数目记作 C ( f ) C(f) C(f),那么等价类的数目就是 C ( f ) C(f) C(f)的平均数
Pólya定理
假设有 k k k种颜色,如果置换 f f f能写成 m ( f ) m(f) m(f)种循环,那么等价类的个数就是 k m ( f ) k^{m(f)} km(f)的平均数
题解
对于项链,显然我们有
n
n
n种置换,我们给项链编号为
0
,
1
,
.
.
.
,
n
−
1
0,1,...,n-1
0,1,...,n−1,对于一种置换如果我把每颗珠子向后移
i
i
i的距离,那么这棵珠子会移到
0
,
g
c
d
(
n
,
i
)
,
2
g
c
d
(
n
,
i
)
,
.
.
.
,
(
n
g
c
d
(
n
,
i
)
−
1
)
g
c
d
(
n
,
i
)
0,gcd(n,i),2gcd(n,i),...,(\frac{n}{gcd(n,i)}-1)gcd(n,i)
0,gcd(n,i),2gcd(n,i),...,(gcd(n,i)n−1)gcd(n,i)
这个循环中的元素个数为
n
g
c
d
(
n
,
i
)
\frac{n}{gcd(n,i)}
gcd(n,i)n
此置换共有
g
c
d
(
n
,
i
)
gcd(n,i)
gcd(n,i)个循环
所以项链个数就是
∑
i
=
0
n
−
1
t
g
c
d
(
n
,
i
)
n
\frac{\sum_{i=0}^{n-1}t^{gcd(n,i)}}{n}
n∑i=0n−1tgcd(n,i)
对于手镯,又多了对称这种置换
当
n
n
n为奇数时,有
n
n
n条对称轴,每种置换循环的个数为
m
(
f
)
=
⌊
n
2
⌋
+
1
m(f)=\lfloor\frac{n}{2}\rfloor+1
m(f)=⌊2n⌋+1
所以答案就是
∑
i
=
0
n
−
1
t
g
c
d
(
n
,
i
)
+
n
t
⌊
n
2
⌋
+
1
2
n
{\sum_{i=0}^{n-1}t^{gcd(n,i)}+nt^{\lfloor\frac{n}{2}\rfloor+1}}\over{2n}
2n∑i=0n−1tgcd(n,i)+nt⌊2n⌋+1
当
n
n
n为偶数时,有穿过点和穿过轴的两种对称轴,最终算出答案是
∑
i
=
0
n
−
1
t
g
c
d
(
n
,
i
)
+
n
2
t
⌊
n
2
⌋
+
1
+
n
2
t
⌊
n
2
⌋
2
n
{\sum_{i=0}^{n-1}t^{gcd(n,i)}+\frac{n}{2}t^{\lfloor\frac{n}{2}\rfloor+1}+\frac{n}{2}t^{\lfloor\frac{n}{2}\rfloor}}\over{2n}
2n∑i=0n−1tgcd(n,i)+2nt⌊2n⌋+1+2nt⌊2n⌋
代码
//置换 polya定理
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll fastpow(ll a, ll b)
{
ll t=a, ans=1;
for(;b;b>>=1,t=t*t)if(b&1)ans*=t;
return ans;
}
ll gcd(ll a, ll b){return !b?a:gcd(b,a%b);}
int main()
{
ll n, t, ans, i;
while(~scanf("%lld%lld",&n,&t))
{
ans=0;
for(i=0;i<n;i++)ans+=fastpow(t,gcd(n,i));
printf("%lld ",ans/n);
if(n&1)ans+=n*fastpow(t,n/2+1);
else ans+=n/2*fastpow(t,n/2)+n/2*fastpow(t,n/2+1);
printf("%lld\n",ans/n/2);
}
return 0;
}