东扯西扯,发现了个性质,就是恰好选的元素里面都是最小数的倍数时,这个肯定成立。
原因:因为我们变换取模,最后对最小值取模之后,这个值就固定了,那么随意换顺序取模,能和mod 最小值一样的,这个序列就成立,所以其它数必然是最小值的倍数,对其他数取模的时候就相当于减去x被最小值。
code
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 5e5+10;
#define IOS ios::sync_with_stdio(0)
#define ull unsigned ll
#define uint unsigned
#define pai pair<int,int>
#define pal pair<ll,ll>
#define IT iterator
#define pb push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);++i)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);--i)
#define endl '\n'
#define ll long long
const ll mod = 998244353;
bool vis[man];
ll quick_mod(int a,int b){
ll ans = 1;
while(b){
if(b&1)ans = ans * a % mod;
a =1ll * a * a % mod;
b >>= 1;
}
return ans;
}
inline ll C(int n,int k){
if(n<k)return 0;
if(n==k||k==0)return 1;
if(n-k<k)k = n - k;
ll res1 = 1,res2 = 1;
for(int i = k;i;--i){
res1 = res1 * (n - i + 1) % mod;
res2 = res2 * i % mod;
}
return res1 * quick_mod(res2,mod-2) % mod;
}
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n,k;
scanf("%d%d",&n,&k);
ll ans = 0;
For(i,1,n){
int cnt = n / i;
ans = (ans + C(cnt-1,k-1))% mod;
}
cout << ans << endl;
return 0;
}