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})\) ,所以 \(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');
}
}
标签:lceil,le,frac,Removing,num,right,Cards,rceil 来源: https://www.cnblogs.com/Ax-Dea/p/15534038.html