まず、シーケンス内の最小数aaを引き出しますa、aaよりも大きいものがあるとしますA係数BBb、次に、回答に対する順序の影響について考えます。
正の整数xxの場合x、x%a%b = x%b%ax \%a \%b = x \%b \%aを満たす必要がありますx %a %b=x %b %a、およびb> a b> aであるためb>>a、所以x%a%b = x%ax \%a \%b = x \%ax %a %b=x %aなので、上記の式はx≡x%b(moda)x \ equiv x \%b \ pmod aバツ≡x %b(m o da )
次に、x = tb + yx = tb + yを設定しますバツ=t b+y、那么tb +y≡y(モード)tb + y \ equiv y \ pmod at b+Y≡Y(m o dA )によるTTtは任意なので、∣ ba | bの場合のみとき| bは、式が常に成り立ちます。
次に、この結論をシーケンス全体に拡張することもできることを理解してください。したがって、シーケンス内のすべての数値は最小数の倍数であるという結論に達します。
次に、1から最小の数を列挙するだけで、範囲内にあるその倍数を見つけ、組み合わせの数のk-1を選択します(最小の数はそれ自体で決定されます)。
#include <bits/stdc++.h>
#define ll long long
#define MAX 1000005
#define P 998244353
using namespace std;
ll n, k;
ll fac[MAX], inv[MAX];
void init(int n){
fac[0] = 1, inv[0] = inv[1] = 1;
for(int i = 1; i <= n; i++) fac[i] = fac[i-1]*i%P;
for(int i = 2; i <= n; i++) inv[i] = (P-P/i)*inv[P%i]%P;
for(int i = 2; i <= n; i++) inv[i] = inv[i]*inv[i-1]%P;
}
ll C(ll n, ll m){
if(!m) return 1;
return fac[n]*inv[m]%P*inv[n-m]%P;
}
int main()
{
init(MAX-1);
cin >> n >> k;
ll ans = 0;
for(int i = 1; i <= n; i++){
if(n/i < k) break;
ans = (ans+C(n/i-1, k-1))%P;
}
cout << ans << endl;
return 0;
}