Educational Codeforces Round 88 (Rated for Div. 2) E. Modular Stability(組合數模板)

E. Modular Stability

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

We define xmodyxmody as the remainder of division of xx by yy (%% operator in C++ or Java, mod operator in Pascal).

Let's call an array of positive integers [a1,a2,…,ak][a1,a2,…,ak] stable if for every permutation pp of integers from 11 to kk, and for every non-negative integer xx, the following condition is met:

(((xmoda1)moda2)…modak−1)modak=(((xmodap1)modap2)…modapk−1)modapk(((xmoda1)moda2)…modak−1)modak=(((xmodap1)modap2)…modapk−1)modapk

That is, for each non-negative integer xx, the value of (((xmoda1)moda2)…modak−1)modak(((xmoda1)moda2)…modak−1)modak does not change if we reorder the elements of the array aa.

For two given integers nn and kk, calculate the number of stable arrays [a1,a2,…,ak][a1,a2,…,ak] such that 1≤a1<a2<⋯<ak≤n1≤a1<a2<⋯<ak≤n.

Input

The only line contains two integers nn and kk (1≤n,k≤5⋅1051≤n,k≤5⋅105).

Output

Print one integer — the number of stable arrays [a1,a2,…,ak][a1,a2,…,ak] such that 1≤a1<a2<⋯<ak≤n1≤a1<a2<⋯<ak≤n. Since the answer may be large, print it modulo 998244353998244353.

題意:給你n,k(1<=k<=n<=5e5),從1到n中選k個數組成一個嚴格遞增序列,如果對任何正整數,依次模上這k個數,無論這k個數如何排列得到的答案都相同,那麼稱這個序列爲好序列,求好序列的個數%998244353

思路:

直接打表就可以發現,一個好序列中所有的數都能整除第一個數(也就是最小的那個數),所以我們利用組合數,枚舉最小的數i,然後從剩下的(n/i)-1個能整除i的數中隨意挑k-1個即可。

即使不打表,也可以推理出來,感興趣的可以試一試(不過直接打表還是香呢)。

代碼:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=1000010;
const long long mod=998244353;
int n,m,q,k,flag,x,f,y,p;
long long ni[maxn];
long long a[maxn];
long long zuhe(int x,int y){  //組合數
    return a[x]*ni[y]%mod*ni[x-y]%mod;
}
long long calc(long long x,long long y){
    long long z=1;
    while (y){
        if (y&1)(z*=x)%=mod;
        (x*=x)%=mod,y/=2;
    }
    return z;
}
int main()
{
    ios::sync_with_stdio(false);
    a[0]=1;
    for (int i=1;i<maxn;i++)a[i]=a[i-1]*i%mod;
    ni[maxn-1]=calc(a[maxn-1],mod-2);
    for (int i=maxn-2;i>=0;i--)
    ni[i]=ni[i+1]*(i+1)%mod;
    cin>>n>>k;
    ll ans=0;
    rep(i,1,n){
        ll t=n/i;
        if(t<k) break;
        ans=(ans+zuhe(t-1,k-1))%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章