#include <bits/stdc++.h>
using namespace std;
class Trie {
private:
static const int MAXN = 1e5 + 5;
static const int BASE = 30;
int idx = 1, trie[MAXN * BASE][2];
int pos[MAXN * BASE]; // pos[i]: 异或前缀为i的最右端点
public:
void insert(int p, int x) {
int u = 1;
for (int i = BASE; i >= 0; --i) {
int v = (x >> i) & 1;
if (!trie[u][v]) trie[u][v] = ++idx;
u = trie[u][v];
pos[u] = max(pos[u], p);
}
}
int find(int x, int k) {
int u = 1, res = -1;
for (int i = BASE; i >= 0; --i) {
int v = (x >> i) & 1;
if ((k >> i) & 1) { // 如果k当前位为1
// 只有当前位x能找和它异或为1的数才有可能大于等于k
// 否则直接返回已经找到的最大值
if (trie[u][v ^ 1]) u = trie[u][v ^ 1];
else return res;
} else { // 如果k当前位为0, x异或后当前位是0是1都有可能大于等于k
// 如果异或后是1, 那肯定大于等于k了, 不用往下再遍历了, 直接尝试更新最大值
// 否则继续往下遍历
if (trie[u][v ^ 1]) res = max(res, pos[trie[u][v ^ 1]]);
u = trie[u][v];
}
}
res = max(res, pos[u]); // 到达最底层即==k的情况
return res;
}
void clear() {
for (int i = 1; i <= idx; ++i) {
pos[i] = 0;
trie[i][0] = trie[i][1] = 0;
}
idx = 1;
}
} tree;
const int MAXN = 1e5 + 5;
int a[MAXN];
int main(int argc, char *argv[]) {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
tree.clear();
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
a[i] ^= a[i - 1];
}
int L = -1, R = n + 1;
for (int r = 1; r <= n; ++r) {
tree.insert(r, a[r]);
int l = tree.find(a[r], k);
if (~l && r - l < R - L) {
L = l, R = r;
}
}
if (L == -1) cout << -1 << '\n';
else cout << L + 1 << ' ' << R << '\n';
}
system("pause");
return 0;
}
2021杭电多校赛第一场
转载
Xor sum
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
上一篇:你真的会二分法吗?
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
一场关于栈的面试----最小栈的实现
一场关于栈的面试----最小栈的实现
最小值 出栈 入栈 -
2019HDU多校第一场
D Vacation
字符串 约束条件 后缀 -
杭电多校第一场 [Fibonacci Sum]
杭电多校第一场 Fibonacci Sum 题解 按照这个博客可以推出式子,但是直接按照这个写会tle,所以要进行优化。 https://.cnblogs.com/lonely
i++ javascript c++ #include #define