题目链接:http://codeforces.com/contest/1359/problem/E
题目大意:
给n和k,求有多少个不含重复元素的序列满足,任意排序之后,对于任意整数,从前到尾进行模运算,结果都是相等的。
序列元素值在1-n之间。
题目思路:
首先想到,当我们碰到那个最小的数字 , 假如说,那么之后的结果就都不会发生改变了。
所以只考虑之前的那些数,要满足什么条件,模完 再模 , 结果相同呢。
不妨我们先缩小问题:
假如有两个数字,b c , 且b<c ,对于任意整数 x 满足 (x%c)%b == (x%b)%c 的条件是什么,首先肯定的是,
(x%b)%c = (x % b) 设x = (k1 为 常数) 所以有 t % b == % b
得 (k1, k2 , k3 均为整数)
可见和 t 是无关的也就是对选择的x无关(真的吗?), 只和b,c关系有关
此时读者可能想,这个式子不是总是存在k1,k2,k3满足嘛?
实际上不是的,我们只是把 t 消去了,但是k1和 t 是有关系的,也就是说当我们选定了一个x之后,k1 就确定了,也就是说选定x后,等式右边是个定值。但是k2和k3是我们可以自己确定的呀。
再结合题目对任意整数都要满足上式子的要求,所以k1不能是决定性因素,所以上式子成立,当且仅当 c % b = = 0
当序列所有值都是最小值的倍数的时候,序列合法。
#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 Pow(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(){
{
int n,k;
cin>>n>>k;
fac[0]=1;
for(int i=1;i<=M-4;i++)
fac[i]=1ll*fac[i-1]*i%mod;
inv[n]=Pow(fac[n],mod-2);
for(int i=n-1;i>=0;i--)
inv[i]=1ll*inv[i+1]*(i+1)%mod;
int ans=0;
//cout<<C(5,2)<<endl;
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;
}