Educational Codeforces Round 88 (Rated for Div. 2)E. Modular Stability

题目:click
题意:问有多少组a[1],a[2]…a[k]对于任意x(x是非负整数), ( ( x m o d    a [ 1 ] ) m o d    a [ 2 ] . . . . ) m o d    a [ k ] ((x\mod a[1])\mod a[2]....)\mod a[k] 该式,任意排列a[1]…a[k],该式值不变,1<=a[i]<=n。
在这里插入图片描述
首先可以确定值肯定在最小的那个a[i]中,以此为突破口进行分析,要使得全排列在这里插入图片描述该式值都不变。
x = a 1 k + y x=a_1*k+y ,mod 最小值时没问题,mod另一个的 a i a_i 时,需要保证y不变,那么其他 a i a_i 必定是 a 1 a_1 的倍数 a i = k ? a 1 a_i=k_?*a_1
即总式子 i = 1 n C n / i 1 k 1 \sum_{i=1}^nC_{n/i-1}^{k-1}

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=998244353;
ll n,k;
ll a[500100];
ll quickpow(ll a,ll nn)
{
    ll res=1;
    while(nn)
    {
        if(nn&1)
            res=(res*a)%mod;
        nn>>=1;
        a=(a*a)%mod;
    }
    return res;
}
void init()
{
    a[0]=1;
    for(ll i=1;i<=n;i++)
    {
        a[i]=(i*a[i-1])%mod;
    }
}
ll C(ll n,ll m)
{
    if(n<m)
        return 0;
    ll temp=(a[n-m]*a[m])%mod;
    ll res=(a[n]*(quickpow(temp%mod,mod-2)%mod))%mod;
    return res;
}
int main()
{
    ll i,j;
    scanf("%I64d %I64d",&n,&k);
    init();
    if(k>n)
    {
        printf("0");
        return 0;
    }
    if(k==1)
    {
        printf("%I64d",n);
        return 0;
    }
    if(n==k)
    {
        printf("1");
        return 0;
    }
    ll ans=0;
    for(i=1;i<=n;i++)
    {
        ans=(ans+C(n/i-1,k-1))%mod;
    }
    printf("%I64d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43958964/article/details/106444693