CF1359E Modular Stability 题解

由于 \(a_1\) 时最小的,所以对于长度为 \(k\) 的序列 \(\{a_i\}\),取模每一项最后的结果是 \(x \bmod a_1\)

而对于下标的任意排列,显然 \(\forall p_i < p_1\),都必须满足 \(x \bmod a_1 = x \bmod a_i\),即 \(a_1 \mid a_i\),不然最后的结果就会改变。当 \(a_1\) 为首项时,就得到了 \(\forall i \in [1,k]\quad a_1 \mid a_i\)

所以,我们只要枚举首项 \(a_1\),在 \([1,n]\) 范围 \(a_1\) 的倍数个数为 \(\lfloor \frac{n}{a_1} \rfloor\),我们要从中选取 \(k-1\) 个数作为其他项,所以答案就是 \[ \sum_{i=1} ^n C_{\lfloor \frac{n}{i} \rfloor -1} ^ {k-1} \] 统计就好了。

#include<cstdio>
#define R register
#define ll long long
#define rep(i,j,k) for(i=(j);i<=(k);++i)
const int N=5e5+5;
const ll p=998244353;
int n, k;
ll fac[N], inv[N], ans;
ll C(ll n,ll m) {
    if(!m) return 1;
    return fac[n]*inv[m]%p*inv[n-m]%p;
}
int main() {
    R int i;
    scanf("%d%d",&n,&k);
    fac[0]=1ll, inv[0]=inv[1]=1ll;
    rep(i,1,5e5) {
        fac[i]=fac[i-1]*i%p;
        if(i!=1) inv[i]=(p-p/i)*inv[p%i]%p;
    }
    rep(i,1,5e5) inv[i]=inv[i]*inv[i-1]%p;
    rep(i,1,n) {
        if(n/i<k) break;
        (ans+=C(n/i-1,k-1))%=p;
    }
    printf("%lld\n",ans);
}

CF1359E Modular Stability 题解
https://yozora0908.github.io/2022/cf1359e-solution/
作者
yozora0908
发布于
2022年4月10日
许可协议