E. Modular Stability(思维构造)
题:https://codeforces.com/contest/1359/problem/E
题意:给定一个n和k,可以构造出k个数的序列{ai},要求,对于一个非负数x,对x连续取序列{ai}取模后的值要等于任意编号序列的{ai}取模后的值。且1<=a1<a2....an<=n,问满足条件的个数。
分析:我们要抓住连续取模,连续取模最后要给最小的一个数ai 取模后值就固定了,那么保持不变的条件就是其余的数要是ai 的倍数才能实现相同。那么就只要对每一个数枚举后面的倍数个数再取组合数即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M=5e5+5; const int mod=998244353; ll fac[M],inv[M]; ll ksm(ll a,ll b){ ll t=1ll; while(b){ if(b&1) t=(t*a)%mod; b>>=1; a=(a*a)%mod; } return t; } ll C(int n,int m){ return fac[n]*inv[m]%mod*inv[n-m]%mod; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,k; cin>>n>>k; fac[0]=1; for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod; inv[n]=ksm(fac[n],mod-2); for(int i=n-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod; int ans=0; for(int i=1;i<=n;i++){ int tmp=n/i-1; if(1+tmp>=k) ans=(ans+C(tmp,k-1))%mod; } cout<<ans<<endl; return 0; }