某多序列二分的神秘做法
给你
显然有一个单次询问
有一个东西叫分散层叠,但我显然是不会这玩意的,但今上午上 whk 的时候乱想了一个做法,时间常数比分散层叠优秀得多,缺点在于空间是
以后继为例,首先有另外一种暴力:把所有的序列都揉到一起排序,对于每个位置
考虑平衡这两个暴力,每
模板题代码:
const int N = 10005;
int n, k, Q, d, tot[9], blen[9], suf[9][N * 12][12];
pair<int, int> a[9][N * 12];
int main() {
cin >> n >> k >> Q >> d;
for (int i = 0, x, b; i < k; i++) {
blen[b = i / 12]++;
for (int j = 1; j <= n; j++) cin >> x, a[b][++tot[b]] = {x, i % 12};
}
int btot = (k - 1) / 12;
for (int i = 0; i <= btot; i++) {
sort(a[i] + 1, a[i] + 1 + tot[i]);
int buc[12]; memset(buc, 0, sizeof(buc));
for (int j = tot[i]; j >= 1; j--) {
buc[a[i][j].second] = a[i][j].first;
for (int k = 0; k < 12; k++) suf[i][j][k] = buc[k];
}
}
int ans = 0, x;
for (int q = 1; q <= Q; q++) {
cin >> x, x ^= ans, ans = 0;
for (int i = 0, p; i <= btot; i++) {
p = lower_bound(a[i] + 1, a[i] + 1 + tot[i], make_pair(x, 0)) - a[i];
for (int j = 0; j < blen[i]; j++) ans ^= suf[i][p][j];
}
if (!(q % d)) cout << ans << '\n';
}
}
跑得很快,仅次于针对题目乱搞的做法。