CF1359E Modular Stability 题解
题目链接:CF1359E Modular Stability
题意:
求有多少个长度为 $k$ 的序列 $a$,满足以下条件:
$\forall 1 \le i < k,a_i < a_{i+1}$
$\forall 1 \le i \le k,1 \le a_i \le n$
对于任意一个 $1$ 至 $k$ 的排列 $p$,满足
其中 $x$ 为任意非负整数。
结果对 $998244353$ 取模。
输入格式:
输入一行两个整数 $n,k$,意义如题目描述所示。
输出格式:
输出一个整数表示答案。
数据范围:
$1 \le n,k \le 5 \times 10^5$。
考虑如何使得 $(x \bmod a) \bmod b = (x \bmod b) \bmod a$ ,其中 $a < b$
稍微搞一搞可以发现上面的式子等价于 $x\equiv x + by \pmod{a}$ ,则 $a \mid b$ 时恒成立
那么有 $a_i \mid a_{i+1}$ ,其中 $i < k$ 。因此我们只需要枚举 $a_1$ ,然后看看有多少倍数合法,从里面选 $k-1$ 个就好
时间复杂度 $\mathcal{O}(n)$
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
const int mod = 998244353;
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
void add(int &x,int y) { (x += y) >= mod ? x -= mod : 0; }
#define N ((int)(1e6 + 15))
int fac[N],inv[N];
void init(int n)
{
fac[0] = 1, inv[0] = inv[1] = 1;
for(int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % mod;
for(int i = 2; i <= n; i++) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
for(int i = 2; i <= n; i++) inv[i] = inv[i] * inv[i - 1] % mod;
}
int C(int n, int m)
{
if(!m) return 1;
return fac[n] * inv[m] % mod * inv[n - m] % mod;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
init((int)(1e6 + 5));
int n,k,res = 0; cin >> n >> k;
for(int i = 1; i <= n; i++)
{
if(n / i < k) break;
add(res, C(n / i - 1, k - 1));
}
cout << res << '\n';
return 0;
}
参考文献: