# 2019 HDU 多校训练第一场 B-Operation

0 l r：从[l，r]中选择一些数字，使它们的异或和最大，输出最大值；
1 x：将x附加到序列的末尾，并让n=n+1。

//这是一份错解
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000005;
int n, q, a[MAXN];
struct L_B
{
int a[32];
void init()
{
memset(a, 0, sizeof(a));
}
bool insert(int val)
{
for (int i = 30; i >= 0; --i)
{
if (val & (1 << i))
{
if (!a[i])
{
a[i] = val;
break;
}
else
val ^= a[i];
}
}
return val > 0;
}
int query_max()
{
int ret = 0;
for (int i = 30; i >= 0; --i)
{
if ((ret ^ a[i]) > ret)
ret ^= a[i];
}
return ret;
}
L_B merge(L_B m)
{
L_B ret;
for (int i = 0; i < 31; i++)
ret.a[i] = a[i];
for (int i = 0; i < 31; i++)
{
for (int j = i; j >= 0; j--)
{
if (m.a[i] & (1 << j))
{
if (ret.a[j])
m.a[i] ^= ret.a[j];
else
{
ret.a[j] = m.a[i];
break;
}
}
}
}
return ret;
}
} tr[MAXN * 4];
void build(int l, int r, int root)
{
if (l == r)
{
tr[root].init();
tr[root].insert(a[l]);
return;
}
int mid = (l + r) >> 1;
build(l, mid, root << 1);
build(mid + 1, r, root << 1 | 1);
tr[root] = tr[root << 1].merge(tr[root << 1 | 1]);
}
void add(int l, int r, int pos, int root, int ans)
{
if (l == pos && r == pos)
{
tr[root].init();
tr[root].insert(ans);
return;
}
int mid = (l + r) >> 1;
if (pos > mid)
add(mid + 1, r, pos, root << 1 | 1, ans);
else
add(l, mid, pos, root << 1, ans);
tr[root] = tr[root << 1].merge(tr[root << 1 | 1]);
}
L_B query(int L, int R, int l, int r, int root)
{
if (L <= l && r <= R)
return tr[root];
int mid = (l + r) >> 1;
if (L <= mid && mid < R)
return query(L, R, l, mid, root << 1).merge(query(L, R, mid + 1, r, root << 1 | 1));
if (L <= mid)
return query(L, R, l, mid, root << 1);
if (R > mid)
return query(L, R, mid + 1, r, root << 1 | 1);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
memset(a, 0, sizeof(a));
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
int len = n + q;
build(1, len, 1);
int lastans = 0, op;
L_B ans;
for (int i = 1; i <= q; ++i)
{
scanf("%d", &op);
if (op == 0)
{
int l, r;
scanf("%d %d", &l, &r);
l = (l ^ lastans) % n + 1;
r = (r ^ lastans) % n + 1;
if (l > r)
swap(l, r);
ans.init();
ans = query(l, r, 1, len, 1);
lastans = ans.query_max();
printf("%d\n", lastans);
}
else if (op == 1)
{
int x;
scanf("%d", &x);
x = x ^ lastans;
n++;
}
}
}
return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000005;
int a[MAXN], L_B[MAXN][31], pos[MAXN][31];
{
int k = p;
for (int i = 30; i >= 0; --i)
{
L_B[p][i] = L_B[p - 1][i];
pos[p][i] = pos[p - 1][i];
}
for (int i = 30; i >= 0; --i)
{
if (x >> i)
{
if (!L_B[p][i])
{
L_B[p][i] = x;
pos[p][i] = k;
break;
}
else
{
if (k > pos[p][i])
{
swap(k, pos[p][i]);
swap(x, L_B[p][i]);
}
x ^= L_B[p][i];
}
}
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int n, q, op, ans = 0;
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
}
while (q--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d", &a[++n]);
a[n] ^= ans;
}
else
{
int l, r;
scanf("%d %d", &l, &r);
l = (l ^ ans) % n + 1;
r = (r ^ ans) % n + 1;
if (l > r)
swap(l, r);
ans = 0;
for (int j = 30; j >= 0; --j)
if ((ans ^ L_B[r][j]) > ans && pos[r][j] >= l)
ans ^= L_B[r][j];
printf("%d\n", ans);
}
}
for (int i = 1; i <= n; ++i)
{
for (int j = 30; j >= 0; --j)
{
L_B[i][j] = 0;
pos[i][j] = 0;
}
}
}
return 0;
}

posted @ 2019-07-30 13:31  redleaves  阅读(134)  评论(0编辑  收藏
Live2D