题解:Removing Cards

Problem Statement

\(N\) 张卡片,从左到右按 \(1\sim N\) 编号,你会做如下操作:

  • 将所有从左到右第 \(Kx + 1\) 张卡片盖章。
  • 将这些被盖章的卡片删除。

求出最后一张被删除的卡片的编号。

给定 \(K\)\(Q\)\(N\) ,对于每个 \(N\) 求出答案。

Constraints

\(1\le K \le 10 ^ 4\)\(1\le Q \le 10 ^ 5\)\(1\le N \le 10 ^ {18}\)

Solution

设答案为 \(f_n\) ,那么有递推式:

\[\begin{cases} f_1 = 1 \\ f_n = f_{n - \lceil\frac{n}{K}\rceil} + \left\lceil\frac{f_{n - \lceil\frac{n}{K}\rceil}}{K - 1}\right\rceil \\ \end{cases} \]

其中 \(n - \lceil\frac{n}{K}\rceil\) 是每一轮剩下的个数,\(\left\lceil\frac{f_{n - \lceil\frac{n}{K}\rceil}}{K - 1}\right\rceil\) 是在 \(n\) 的情况下,\(n - \lceil\frac{n}{K}\rceil\) 的这个位置前面被删去的个数。

然后获得了一个 \(\mathcal O (n)\) 的算法。

然后一搞这个柿子,容易发现这是单调递增的,每个相同数字的端点比较稀疏。

设每个端点的位置为 \(X_i\) ,即对于所有 \(f_k = i\) ,有 \(X_i \le k < X_{i + 1}\)

然后考虑每个 \(X_{i + 1}\leftarrow X_{i}\) 的过程,考虑每个 \(X_i\) 能转移到的位置的范围,然后得出:

\[X_{i + 1} - \left\lceil\frac{X_{i + 1}}{K}\right\rceil = X_i \]

由于都会初中数学,所以得到:

\[KX_i \le (K - 1) X_{i + 1} < (K + 1) X_i \]

然后就有:

\[\begin{cases} X_1 = 1 \\ X_n = X_{n - 1} + \left\lceil\frac{X_{n - 1}}{K - 1}\right\rceil \end{cases} \]

这显然是对的。

然后分析一下算 \(X\) 的复杂度,对于一个巨大的 \(n\)\(X_{i + 1}\ge (1 + \frac{1}{K - 1})X_i\) ,所以 \(T(n) \le 1 + \log_{(1 + \frac{1}{K - 1})} n \le 1 + k\log n\)

最神奇的是这两个东西的递推式是一样的。

int K, Q; i64 n, X[N], F[N], num;
inline i64 CiL(i64 A, i64 B) {
	return (A + B - 1) / B;
}
inline void solve() {
	Rdn(K, Q);
	X[++num] = 1, F[num] = 1;
	while (X[num] < 1e18) X[num + 1] = X[num] + CiL(X[num], K - 1), ++num, F[num] = F[num - 1] + CiL(F[num - 1], K - 1);
	while (Q--) {
		Rdn(n);
		Wtn(F[upper_bound(X + 1, X + num + 1, n) - X - 1], '\n');
	}
}
posted @ 2021-11-10 16:24  AxDea  阅读(28)  评论(0编辑  收藏  举报