其他分享
首页 > 其他分享> > Removing Cards

Removing Cards

作者:互联网

Problem Statement

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

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

给定 \(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