题目链接(加强,略有不同)
题意
问有多少种本质不同的项链,满足:
- 有 (n) 个黑色珠子,(m) 个白色珠子;
- 连续的白色珠子不超过 (k) 个。
旋转同构算作相同,翻转同构算作不同。
(n,mleq 10^6),(Tleq 5) 组询问。
题解
Burnside 引理,于是不考虑本质不同的限制。
先假设项链从黑色珠子开始,最后乘上 (dfrac{n'+m'}{n'}) 即可。考虑项链是由许多 黑+白*i
的段拼成的,故答案为:
[[x^{m+n}] (x+x^2+cdots +x^{k+1})^n=[x^m] (x^0+x^1+cdots +x^k)^n
]
考虑其组合意义:用 (n) 个不大于 (k) 的数凑出 (m),于是容斥枚举多少个数大于 (k):
[sum_{i=0}^n (-1)^idbinom{n}{i}dbinom{m-1-i(k+1)}{n-1}
]
#include<bits/stdc++.h>
using namespace std;
const int N=4e6,mod=998244353,G=3;
int qpow(int x,int y){
int ans=1;
while(y){
if(y&1)ans=ans*1ll*x%mod;
x=x*1ll*x%mod;
y>>=1;
}
return ans;
}
int fac[N],ifac[N];
int binom(int n,int m){
if(m<0||m>n)return 0;
return fac[n]*1ll*ifac[m]%mod*ifac[n-m]%mod;
}
int t=0;
int calc(int n,int m,int k){
int ans=0;
m=n-m;
for(int i=0;i*(k+1)<n&&i<=m;i++)
ans=(ans+(i&1?mod-1ll:1ll)*binom(m,i)%mod*binom(n-1-i*(k+1),m-1))%mod;
ans=ans*1ll*t%mod;
return ans;
}
int gcd(int x,int y){
return x?gcd(y%x,x):y;
}
int q[N];
int main(){
int T;cin>>T;
while(T--){
int n,m,k;
cin>>n>>m>>k;
t=qpow(n-m,mod-2)*1ll*n%mod;
if(n==m){
printf("%d
",k==n);
continue;
}
fac[0]=1;for(int i=1;i<=n+m;i++)fac[i]=fac[i-1]*1ll*i%mod;
ifac[n+m]=qpow(fac[n+m],mod-2);
for(int i=n+m-1;i>=0;i--)ifac[i]=ifac[i+1]*(i+1ll)%mod;
int sum=0,g=gcd(n,m);
for(int i=1;i<=n;i++)q[i]=0;
for(int i=1;i<=n;i++){
int t=n/gcd(n,i);
if(m%t)continue;
if(n%i==0)
sum=(sum+(q[t]=calc(n/t,m/t,k)))%mod;
else
sum=(sum+q[t])%mod;
}
printf("%d
",sum*1ll*qpow(n,mod-2)%mod);
}
}