TLE 求助+求解释代码(悬关)
查看原帖
TLE 求助+求解释代码(悬关)
726139
残阳如血楼主2024/6/29 11:58

代码对着题解看的,现在只理解了一部分。。。

对于有 //qwqqwq.. 的那一行,我看题解说的是不跳到最后,那么题解为什么 20∼020\sim0 枚举啊?

顺便求求给代码解释一下,谢谢。

#include <cstring>
#include <iostream>
const int N = 1e5 + 10;

int T, n, a[N], q;
int nxt[N][30], pos[15];
// nxt[i][j]:后面的第 2^j 个与 a[i] 相等的值的位置
// pos[i]:当前最前面的一个 i 的位置

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	for (std::cin >> T; T; --T) {
		std::cin >> n;
		memset(pos, 0, sizeof(pos)); // 多测清空
		for (int i = 1; i <= n; ++i) {
			std::cin >> a[i];
			for (int j = 0; j <= 20; ++j) // 全部初始化
				nxt[i][j] = n + 1; // 初始化为一个极大值
		}
		for (int i = n; i; --i) {
			if (pos[a[i]] == 0) { // 不存在下一个 a[i]
				nxt[i][0] = n + 1; // 下一个即为一个极大值
				pos[a[i]] = i; // pos[a[i]] 是当前的位置
			} else { // 存在下一个 a[i]
				nxt[i][0] = pos[a[i]]; // 下一个
				pos[a[i]] = i; // pos[a[i]] 是当前的位置
 			}
		}
		for (int i = n; i; --i) { // 第 i 个位置
			for (int j = 1; j <= 20; ++j) // 向后 2^j 步
				if (nxt[i][j - 1] + 1 <= n) { // 当前位置下一个相同值不是最后一个数
					nxt[i][j] = nxt[nxt[i][j - 1] + 1][j - 1]; // 
				}
		}
		std::cin >> q;
		for (int l, r, i, ans; q; --q) {
			std::cin >> l >> r, i = l, ans = 0;
			while (i <= r) {
				while (i <= r && nxt[i][0] > r) ++i, ++ans; // [l,r] 内部存在下一个相同值,持续向后移动
				if (i > r) break; // 出界
				for (int j = 0; j <= 20; ++j) // qwqqwq
					if (nxt[i][j] <= r) {
						i = nxt[i][j];
						break;
					}
				++i;
			}
			std::cout << ans << '\n';
		}
	}
	std::cout.flush();
	return 0;
}
2024/6/29 11:58
加载中...