Description
给定一个非负整数序列{a},初始长度为N。
有M个操作,有以下两种操作类型:
1、Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
2、Qlrx:询问操作,你需要找到一个位置p,满足l<=p<=r,使得:
a[p] xor a[p+1] xor … xor a[N] xor x 最大,输出最大是多少。
Input
第一行包含两个整数 N ,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列 A 。
接下来 M行,每行描述一个操作,格式如题面所述。
Output
假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。
Sample Input
5 5
2 6 4 3 6
A 1
Q 3 5 4
A 4
Q 5 7 0
Q 3 6 6
对于测试点 1-2,N,M<=5 。
对于测试点 3-7,N,M<=80000 。
对于测试点 8-10,N,M<=300000 。
其中测试点 1, 3, 5, 7, 9保证没有修改操作。
0<=a[i]<=10^7。
Sample Output
4
5
可持久化0/1trie模板吧….
有一个WA点,直接建的话相当于查
l−2
l
−
2
~
r−1
r
−
1
一开始没处理,最好是在开头插个0
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define file(k) memset(k,0,sizeof(k))
#define ll long long
#define N 600000
int n , q , totr;
int root[N+1] , a[N+1];
struct trie{
int tot;
int tr[N*24+5][2] , sum[N*24+5];
int insert(int root,int last,int val)
{
int tmp = root = ++tot;
repp(i,23,0)
{
tr[root][0] = tr[last][0];tr[root][1] = tr[last][1];
sum[root] = sum[last] + 1;
int k = (val>>i)&1;
tr[root][k] = ++tot;
root = tr[root][k];
last = tr[last][k];
}
sum[root] = sum[last] + 1;
return tmp;
}
int query(int x,int y,int val)
{
int ans = 0;
repp(i,23,0)
{
int k = (val>>i)&1;
if(sum[tr[y][k^1]] - sum[tr[x][k^1]])
ans += 1<<i,
x = tr[x][k^1],
y = tr[y][k^1];
else x = tr[x][k] , y = tr[y][k];
}
return ans;
}
}trie;
int read()
{
int sum = 0;char c = getchar();bool flag = true;
while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
if(!flag) sum = -sum;
return sum;
}
void init()
{
n = read();q = read();
root[1] = trie.insert(root[1],root[0],0);
rep(i,2,n+1)
{
int x = read();
a[i] = x ^ a[i-1];
root[i] = trie.insert(root[i],root[i-1],a[i]);
}
totr = n+1;
return;
}
int main()
{
init();
rep(i,1,q)
{
char k = getchar();
while(k != 'A' && k != 'Q') k = getchar();
if(k == 'A')
{
int x = read();
a[++totr] = a[totr-1] ^ x;
root[totr] = trie.insert(root[totr],root[totr-1],a[totr]);
}
else
{
int l = read() , r = read() , x = read();
x ^= a[totr];
printf("%d\n",trie.query(root[l-1],root[r],x));
}
}
return 0;
}