E. Modular Stability
题目 problem
题意:给[1,n]个数,从中选择不同的k个数字使之满足,对于任意非负整数x满足
p为选中这k个数字的全排列。(答案对998244353 取模)
题解:本题是有规律的,找出最小的 a
1
{_1}
1,剩下的a
2
{_2}
2,a
3
{_3}
3…a
k
{_k}
k必须为a1的倍数才能满足条件。
反证法:a
m
{_m}
m 不为a
1
{_1}
1的倍数,当x=a
m
{_m}
m时,x%a
m
{_m}
m==0,
((x%a
1
{_1}
1)%…)%a
k
{_k}
k!=0 ==>
((x%a
1
{_1}
1)%…)%a
k
{_k}
k!=((x%a
m
{_m}
m)%a
1
{_1}
1…)%a
k
{_k}
k
反证法可知,a
2
{_2}
2,a
3
{_3}
3…a
k
{_k}
k必须被a1整除才能满足条件。
就易得答案公式: ∑ i = 1 n c n i − 1 k − 1 \sum_{i=1}^{n} {c_{\frac{n}{i}-1}^{k-1}} ∑i=1ncin−1k−1。
由于答案会很大,所以需要取模,在取模时用到了逆元,打个表O(n)时间复杂度就搞定啦!!
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e5+10;
const int mod=998244353;
ll a[N],f[N],inv[N];
void init()
{
inv[1]=1;
for(int i=2;i<N-10;i++)
{
inv[i]=inv[mod%i]*(mod-mod/i)%mod;
}
f[0]=inv[0]=1;
for(int i=1;i<N-10;i++)
{
f[i]=i*f[i-1]%mod;
inv[i]=inv[i]*inv[i-1]%mod;
}
}
ll c(int m,int n)
{
if(m<0 || m>n) return 0;
return f[n]*inv[n-m]%mod*inv[m]%mod;
}
int main(int argc, char *argv[]) {
int n,k;
cin >> n >> k;
init();
ll ans=0;
for(int i=1;i<=n;i++)
{
ans=(ans+c(k-1,n/i-1))%mod;
}
cout << ans << endl;
}