【题解】 CF1359E 【Modular Stability】

我们先拉出序列中最小的那个数 a a a,假设现在有一个大于 a a a的模数 b b b,那么思考一下它们的顺序对答案的影响。

对于任意正整数 x x x,我们要满足 x % a % b = x % b % a x\%a\%b= x\%b\%a x%a%b=x%b%a,又因为 b > a b>a b>a,所以 x % a % b = x % a x\%a\%b=x\%a x%a%b=x%a,所以上式即 x ≡ x % b ( m o d a ) x \equiv x\% b\pmod a xx%b(moda)

然后设 x = t b + y x=tb+y x=tb+y,那么 t b + y ≡ y ( m o d a ) tb+y\equiv y \pmod a tb+yy(moda),由于 t t t是任意的,所以只有当 a ∣ b a|b ab时,等式恒成立。

那么意会一下,这个结论也可以推广到整个数列,于是我们得出结论:序列中的每一个数都是最小的那个数的倍数。

那么我们只要从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;
}

猜你喜欢

转载自blog.csdn.net/qq_30115697/article/details/109486329