オペレーション(HDU - 6579)
番外:
初心者リニアグループは、推奨リニアベースの研究ノートを。
線形二素子群は、要素又は全く冗長性二排他的集合です。
私たちは、セットのすべてのレコード現在のデジタルビットに貢献して、あなたは間隔または異なる両極端を照会することができます。
質問の意味:
2つの動作モードをサポートするために必要な初期配列に:
- 最大間隔内のXORクエリー要素。
- 配列の最後に要素を追加します。
ソリューション:
私たちは、接頭辞リニアベースを行うことを検討してから右に可能な限りその高い要素の寄与はできるだけ多くを確保するために、同じ時刻に要素を挿入するための座標を記録します。これは、各クエリ間隔線形ベースとできるだけ多数(位置はできるだけ高い貢献)までの時間で、クエリことを確実にします。クエリは、クエリよりも大きいかまたはそれにLに等しい座標場合。
#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int maxn = 1e6 + 5;
typedef pair<int, int> Pair;
struct LinearBasis{
#define N 30
Pair a[N+1];
void init() {
memset(a, 0, sizeof(a));
}
bool insert(int val, int pos) {
for (int i = N; i >= 0; i--) if (val & (1ll << i)) {
if (a[i].first == 0) {
a[i].first = val;
a[i].second = pos;
break;
}
else if (a[i].second < pos) {
swap(val, a[i].first);
swap(pos, a[i].second);
}
val ^= a[i].first;
}
return val > 0;
}
int query_Max(int l) {
int res = 0;
for (int i = N; i >= 0; i--)
if ((res^a[i].first) > res && a[i].second >= l)
res ^= a[i].first;
return res;
}
}LB[maxn];
int T, n, m;
LL x;
int main() {
//fopi;
scanf("%d", &T);
for (int ca = 1; ca <= T; ca++) {
LB[0].init();
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld", &x);
LB[i] = LB[i-1];
LB[i].insert(x, i);
}
int ans = 0;
for (int i = 1; i <= m; i++) {
int op, x, y;
scanf("%d%d", &op, &x);
if (op == 0) {
scanf("%d", &y);
x = (x^ans) % n + 1, y = (y^ans) % n + 1;
if (x > y) swap(x, y);
printf("%d\n", ans = LB[y].query_Max(x));
}
else {
++n;
LB[n] = LB[n-1];
LB[n].insert(x^ans, n);
}
}
}
}