Operation
Problem Description
There is an integer sequence a of length n and there are two kinds of operations:
0 l r: select some numbers from al…ar so that their xor sum is maximum, and print the maximum value.
1 x: append x to the end of the sequence and let n=n+1.
Input
There are multiple test cases. The first line of input contains an integer T(T≤10), indicating the number of test cases.
For each test case:
The first line contains two integers n,m(1≤n≤5×105,1≤m≤5×105), the number of integers initially in the sequence and the number of operations.
The second line contains n integers a1,a2,…,an(0≤ai<230), denoting the initial sequence.
Each of the next m lines contains one of the operations given above.
It’s guaranteed that ∑n≤106,∑m≤106,0≤x<230.
And operations will be encrypted. You need to decode the operations as follows, where lastans denotes the answer to the last type 0 operation and is initially zero:
For every type 0 operation, let l=(l xor lastans)mod n + 1, r=(r xor lastans)mod n + 1, and then swap(l, r) if l>r.
For every type 1 operation, let x=x xor lastans.
Output
For each type 0 operation, please output the maximum xor sum in a single line.
Sample Input
1
3 3
0 1 2
0 1 1
1 3
0 3 4
Sample Output
1
3
思路
给出n个数,然后给出两种操作,一种是往数组加一个数,另一种是求出给定区间的最大异或值。贪心,但是不知道异或应该怎么贪,专门去看了线性基详解,大概能够理解一点,给出的几个模板刚好能够用上。估计这道题卡时间,补题过程中各种TLE,MLE,把数组缩小,输入输出全部改掉,修了一个下午的bug终于AC了。
代码
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+5;
typedef long long ll;
#define debug printf("debug\n");
int t,n,m,p,cot;
ll lastans;
int a,d[maxn][31],pos[maxn][31]; //这里的31我开大一点就炸了
void add(int x) {
for(int i=0; i<=30; i++) {
d[cot][i] = d[cot-1][i];
pos[cot][i] = pos[cot-1][i];
}
for(int i=30; i>=0; i--) {
if(x&(1<<i)) { //注意,如果i大于31,前面的1的后面一定要加ll
if(d[cot][i]) {
if(p > pos[cot][i]) {
swap(d[cot][i],x);
swap(pos[cot][i],p);
}
x^=d[cot][i];
} else {
d[cot][i] = x;
pos[cot][i] = p;
break;//记得如果插入成功一定要退出
}
}
}
}
int zeroDecrypt(int num) {
return (num ^ lastans) % n + 1;
}
ll zeroOperation(int l, int r) {
ll ans = 0;
for(int i=30; i>=0; i--) {//记得从线性基的最高位开始
if(pos[r][i] >= l) {
ans = max(ans^d[r][i],ans);
}
}
return ans;
}
int oneDecrypt(int num) {
return num ^ lastans;
}
int main() {
while(scanf("%d",&t) != EOF) {
while(t--) {
memset(d, 0, sizeof(d));
memset(pos, 0, sizeof(pos));
scanf("%d%d",&n,&m);
lastans = 0;
cot = 0;
for(int i=1; i<=n; i++) {
cin >> a;
cot = p = i;
add(a);
}
int make,l,r,x;
while(m--) {
scanf("%d",&make);
switch(make) {
case 0 : {
scanf("%d%d",&l,&r);
l = zeroDecrypt(l);
r = zeroDecrypt(r);
if(l > r) {
swap(l,r);
}
lastans = zeroOperation(l,r);
printf("%lld\n",lastans);
break;
}
case 1 : {
scanf("%d",&x);
x = oneDecrypt(x);
cot = p = ++n;
add(x);
break;
}
}
}
}
}
}