题目
https://gmoj.net/senior/#main/show/6084
题目大意
你要在一个长度为 n n n 的环中选择 m m m 个点,把它们染成金色,要求没有连续的超过 k k k 个点被染成金色,求有多少个旋转后各不相同的染完色的环。
题解
首先,若
f
x
,
y
f_{x,y}
fx,y 表示将一个长度为
x
x
x 的环中的
y
y
y 个点变成金色,最长的连续金色段长度小于等于
k
k
k 的方案数。由 Pόlya定理 得
a
n
s
=
∑
d
∣
gcd
(
n
,
m
)
f
(
n
d
,
m
d
)
φ
(
d
)
n
ans=\frac{\sum_{d|\gcd{(n,m)}} f\left(\frac{n}{d},\frac{m}{d}\right)\varphi(d)}{n}
ans=n∑d∣gcd(n,m)f(dn,dm)φ(d)
把
f
f
f 写成生成函数的形式:
F
a
,
b
(
x
)
=
(
∑
i
=
0
k
x
i
)
a
−
b
−
1
[
∑
i
=
0
k
(
i
+
1
)
x
i
]
F_{a,b}(x)=\left(\sum_{i=0}^k x^i \right)^{a-b-1} \left[\sum_{i=0}^k (i+1)x^i \right]
Fa,b(x)=(i=0∑kxi)a−b−1[i=0∑k(i+1)xi]
上式考虑的是在
a
−
b
a-b
a−b 个不染色点之间插入
b
b
b 个金色点的方案。后面的部分表示在
n
n
n 号点和
1
1
1 号点之间的间隙中插入的方案,前面的部分表示在剩下的
a
−
b
−
1
a-b-1
a−b−1 个间隙中插入的方案。
那么
a
n
s
=
∑
d
∣
gcd
(
n
,
m
)
[
x
m
d
]
F
n
d
,
m
d
(
x
)
⋅
φ
(
d
)
n
ans=\frac{\sum_{d|\gcd{(n,m)}} \left[x^{\frac{m}{d}}\right]F_{\frac{n}{d},\frac{m}{d}}(x)\cdot \varphi(d)}{n}
ans=n∑d∣gcd(n,m)[xdm]Fdn,dm(x)⋅φ(d)
现在考虑怎么求 F F F ,首先是怎么把后面那坨 [ ∑ i = 0 k ( i + 1 ) x i ] \left[\sum_{i=0}^k (i+1)x^i \right] [∑i=0k(i+1)xi] 化掉。
令
G
k
(
x
)
=
∑
i
=
0
k
(
i
+
1
)
x
i
G_k(x)=\sum_{i=0}^k (i+1)x^i
Gk(x)=∑i=0k(i+1)xi ,发现
G
k
(
x
)
+
(
k
+
2
)
x
k
+
1
=
G
k
+
1
(
x
)
=
G
k
(
x
)
x
+
∑
i
=
0
k
+
1
x
i
G
(
x
)
=
1
+
(
k
+
1
)
x
k
+
2
−
(
k
+
2
)
x
k
+
1
(
x
−
1
)
2
\begin{aligned} G_k(x)+(k+2)x^{k+1}&=G_{k+1}(x)=G_k(x)x+\sum_{i=0}^{k+1} x^i\\ G(x)&=\frac{1+(k+1)x^{k+2}-(k+2)x^{k+1}}{(x-1)^2} \end{aligned}
Gk(x)+(k+2)xk+1G(x)=Gk+1(x)=Gk(x)x+i=0∑k+1xi=(x−1)21+(k+1)xk+2−(k+2)xk+1
令
H
=
1
+
(
k
+
1
)
x
k
+
2
−
(
k
+
2
)
x
k
+
1
H=1+(k+1)x^{k+2}-(k+2)x^{k+1}
H=1+(k+1)xk+2−(k+2)xk+1 ,那么
F
a
,
b
(
x
)
=
(
∑
i
=
0
k
x
i
)
a
−
b
−
1
[
∑
i
=
0
k
(
i
+
1
)
x
i
]
=
(
x
k
+
1
−
1
)
a
−
b
−
1
(
x
−
1
)
a
−
b
−
1
⋅
H
(
x
−
1
)
2
等比数列求和
=
(
1
−
x
k
+
1
)
a
−
b
−
1
(
1
−
x
)
a
−
b
+
1
⋅
H
=
(
1
−
x
k
+
1
)
a
−
b
−
1
(
1
−
x
)
−
(
a
−
b
+
1
)
H
=
[
∑
i
=
0
+
∞
(
a
−
b
−
1
i
)
(
−
1
)
i
x
(
k
+
1
)
i
]
[
∑
i
=
0
+
∞
(
a
−
b
+
i
i
)
x
i
]
H
广义二项式定理
\begin{aligned} F_{a,b}(x)&=\left(\sum_{i=0}^k x^i \right)^{a-b-1} \left[\sum_{i=0}^k (i+1)x^i \right]\\ &=\frac{\left(x^{k+1}-1\right)^{a-b-1}}{(x-1)^{a-b-1}}\cdot\frac{H}{(x-1)^2} &\text{等比数列求和} \\ &=\frac{\left(1-x^{k+1} \right)^{a-b-1} }{(1-x)^{a-b+1} } \cdot H\\ &=\left(1-x^{k+1} \right)^{a-b-1} (1-x)^{-(a-b+1)}H\\ &=\left[\sum_{i=0}^{+\infty} \binom{a-b-1}{i} (-1)^i x^{(k+1)i} \right]\left[\sum_{i=0}^{+\infty}\binom{a-b+i}{i}x^i \right]H &\text{广义二项式定理} \end{aligned}
Fa,b(x)=(i=0∑kxi)a−b−1[i=0∑k(i+1)xi]=(x−1)a−b−1(xk+1−1)a−b−1⋅(x−1)2H=(1−x)a−b+1(1−xk+1)a−b−1⋅H=(1−xk+1)a−b−1(1−x)−(a−b+1)H=[i=0∑+∞(ia−b−1)(−1)ix(k+1)i][i=0∑+∞(ia−b+i)xi]H等比数列求和广义二项式定理
也就是
F
a
,
b
(
x
)
=
[
∑
i
=
0
+
∞
(
a
−
b
−
1
i
)
(
−
1
)
i
x
(
k
+
1
)
i
]
[
∑
j
=
0
+
∞
(
a
−
b
+
j
j
)
x
j
]
[
1
+
(
k
+
1
)
x
k
+
2
−
(
k
+
2
)
x
k
+
1
]
F_{a,b}(x)=\left[\sum_{i=0}^{+\infty} \binom{a-b-1}{i} (-1)^i x^{(k+1)i} \right]\\\left[\sum_{j=0}^{+\infty}\binom{a-b+j}{j}x^j \right]\left[1+(k+1)x^{k+2}-(k+2)x^{k+1} \right]
Fa,b(x)=[i=0∑+∞(ia−b−1)(−1)ix(k+1)i][j=0∑+∞(ja−b+j)xj][1+(k+1)xk+2−(k+2)xk+1]
把最后那个中括号展开之后,可以得到三个互不干扰的式子。发现对于每个式子,只要知道
i
i
i ,就可以得到
j
j
j 。
那么就可以求出
[
x
b
]
F
a
,
b
(
x
)
\left[x^b\right]F_{a,b}(x)
[xb]Fa,b(x) 了。令
S
1
=
∑
i
=
0
⌊
b
k
+
1
⌋
(
−
1
)
i
(
a
−
b
−
1
i
)
(
a
−
i
(
k
+
1
)
b
−
i
(
k
+
1
)
)
,
S
2
=
(
k
+
2
)
∑
i
=
0
⌊
b
−
k
−
1
k
+
1
⌋
(
−
1
)
i
(
a
−
b
−
1
i
)
(
a
−
k
−
1
−
i
(
k
+
1
)
b
−
k
−
1
−
i
(
k
+
1
)
)
,
S
3
=
(
k
+
1
)
∑
i
=
0
⌊
b
−
k
−
2
k
+
1
⌋
(
−
1
)
i
(
a
−
b
−
1
i
)
(
a
−
k
−
2
−
i
(
k
+
1
)
b
−
k
−
2
−
i
(
k
+
1
)
)
\begin{aligned} S_1 &=\sum_{i=0}^{\left\lfloor\frac{b}{k+1} \right\rfloor} (-1)^i \binom{a-b-1}{i}\binom{a-i(k+1)}{b-i(k+1)},\\ S_2 &=(k+2)\sum_{i=0}^{\left\lfloor\frac{b-k-1}{k+1} \right\rfloor} (-1)^i \binom{a-b-1}{i}\binom{a-k-1-i(k+1)}{b-k-1-i(k+1)},\\ S_3 &=(k+1)\sum_{i=0}^{\left\lfloor\frac{b-k-2}{k+1} \right\rfloor} (-1)^i \binom{a-b-1}{i}\binom{a-k-2-i(k+1)}{b-k-2-i(k+1)} \end{aligned}
S1S2S3=i=0∑⌊k+1b⌋(−1)i(ia−b−1)(b−i(k+1)a−i(k+1)),=(k+2)i=0∑⌊k+1b−k−1⌋(−1)i(ia−b−1)(b−k−1−i(k+1)a−k−1−i(k+1)),=(k+1)i=0∑⌊k+1b−k−2⌋(−1)i(ia−b−1)(b−k−2−i(k+1)a−k−2−i(k+1))
那么
[
x
b
]
F
a
,
b
(
x
)
=
S
1
−
S
2
+
S
3
\left[x^b\right]F_{a,b}(x)=S_1-S_2+S_3
[xb]Fa,b(x)=S1−S2+S3 。
#include<cstdio>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define M 1000005
#define N 2000005
const int P=998244353;
int fac[N],ifac[N],inv[N],phi[M],pri[M];
bool tag[M];
inline int get_gcd(int x,int y)
{
int r=x%y;
while(r) x=y,y=r,r=x%y;
return y;
}
inline int C(int x,int y)
{
return 1LL*fac[x]*ifac[y]%P*ifac[x-y]%P;
}
inline void add(int &x,int y){x+=y;if(x>=P) x-=P;}
int main()
{
freopen("gift.in","r",stdin);
freopen("gift.out","w",stdout);
register int i,j,d;
int T,n,m,k,a,b,gcd,lim,s1,s2,s3,sum,ans,now,s=0;
phi[1]=1;
fo(i,2,1000000)
{
if(!tag[i]) pri[++s]=i,phi[i]=i-1;
fo(j,1,s)
{
if(i*pri[j]>1000000) break;
tag[i*pri[j]]=1;
if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
fac[0]=1;fo(i,1,2000000) fac[i]=1LL*fac[i-1]*i%P;
inv[1]=1;fo(i,2,2000000) inv[i]=1LL*inv[P%i]*(P-P/i)%P;
ifac[0]=1;fo(i,1,2000000) ifac[i]=1LL*ifac[i-1]*inv[i]%P;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
if(m==0){puts("1");continue;}
ans=0,gcd=get_gcd(n,m);
fo(d,1,gcd) if(gcd%d==0)
{
a=n/d,b=m/d;
if(a-b==0) continue;
s1=s2=s3=sum=0;
lim=b/(k+1),j=b;
fo(i,0,lim)
{
now=1LL*C(a-b-1,i)*C(a-b+j,j)%P;
add(s1,i&1?P-now:now);
j-=k+1;
}
add(sum,s1);
if(b>=k+1)
{
--lim,j=b-k-1;
fo(i,0,lim)
{
now=1LL*C(a-b-1,i)*C(a-b+j,j)%P;
add(s2,i&1?now:P-now);
j-=k+1;
}
sum=(sum+1LL*(k+2)*s2)%P;
if(b>=k+2)
{
lim=(b-k-2)/(k+1),j=b-k-2;
fo(i,0,lim)
{
now=1LL*C(a-b-1,i)*C(a-b+j,j)%P;
add(s3,i&1?P-now:now);
j-=k+1;
}
sum=(sum+1LL*(k+1)*s3)%P;
}
}
ans=(ans+1LL*sum*phi[d])%P;
}
printf("%lld\n",1LL*ans*inv[n]%P);
}
return 0;
}