E. Modular Stability
给出一个n
要求统计出有多少长度为k的数组 1<=i<=k; 1<=ai<=n
使得它的所有排列 对于任何数x都有
x mod a1 mod a2 mod a3 mod a4 … mod ak = x mod a[i1] mod a[i2] mod a[i3] … mod a[ik]
i1 , i2 , i3 …. ik 是 1到k的所有排列情况
首先需要发现一个事实即
当且仅当 所有ai mod min{aj | 1<=j<=k } ==0 或者说所有ai都能被其中最小的数aj整除
那么无论数组ai如何排列 对任意数x取模的最终结果是相同的
假设 a为数组中最小的数
x mod a mod ka =x mod ka mod a = x mod a
假设数组中存在一个m mod a !=0
那么 若x=a
则 x mod a=0 之后无论mod何数都为0
而 x mod m!=0 最后不一定为0
剩下的就是用逆元取组合数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| # include <bits/stdc++.h>
using namespace std; typedef long long ll;
# define endl '\n'
# define Turnoff std::ios::sync_with_stdio(false)
const ll Max=5e5+5; const ll mod=998244353; ll fac[Max]; void intn(){ fac[0]=1; for(ll i=1;i<Max;i++)fac[i]=(fac[i-1]*i)%mod; } ll qpow(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=(ans*x)%mod; x=(x*x)%mod;y>>=1; } return ans; } ll combin(ll total,ll need){ return (fac[total]*qpow(fac[need]*fac[total-need]%mod,mod-2))%mod; } int main(){ Turnoff; intn();ll ans=0; int n,k;cin>>n>>k; for(int i=1;i<=n;i++){ if(n/i<k)continue; ll have=n/i-1; ans=(ans+combin(have,k-1))%mod; } cout<<ans<<endl; }
|