Description
题目描述
给定一个非负整数序列 {a},初始长度为n。
有 m 个操作,有以下两种操作类型:
A x
:添加操作,表示在序列末尾添加一个数 x,序列的长度 n+1。Q l r x
:询问操作,你需要找到一个位置 p,满足l≤p≤r,使得: a[p]^a[p+1]^...^a[N]^x 最大,输出最大是多少。
输入格式
第一行包含两个整数 N,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列A。
接下来 M行,每行描述一个操作,格式如题面所述。
输出格式
假设询问操作有 T 个,则输出应该有 T行,每行一个整数表示询问的答案。
Code
#include <cstdio> #include <cstdlib> using namespace std; const int N=6e5+10; int rt[N],tot,sum,n,m,l,r,x; char s[5]; struct node { int ch[2],sum; }f[N*40]; void build(int x,int y,int t,int pos) { if(t<0) return ; int wh=(pos>>t)&1; f[x].ch[wh^1]=f[y].ch[wh^1]; f[x].ch[wh]=++tot; f[f[x].ch[wh]].sum=f[f[y].ch[wh]].sum+1; build(f[x].ch[wh],f[y].ch[wh],t-1,pos); } int get(int x,int y,int t,int pos) { if(t<0) return 0; int wh=(pos>>t)&1; int cn=f[f[y].ch[wh^1]].sum-f[f[x].ch[wh^1]].sum; if(cn>0) return (1<<t)+get(f[x].ch[wh^1],f[y].ch[wh^1],t-1,pos); else return get(f[x].ch[wh],f[y].ch[wh],t-1,pos); } int main() { scanf("%d%d",&n,&m); rt[1]=++tot; build(rt[1],rt[0],24,0); for(int i=1;i<=n;i++) { scanf("%d",&x); sum^=x; rt[i+1]=++tot; build(rt[i+1],rt[i],24,sum); } while(m--) { scanf("%s",s); if(s[0]=='Q') { scanf("%d%d%d",&l,&r,&x); x^=sum; printf("%d\n",get(rt[l-1],rt[r],24,x)); } else { scanf("%d",&x); n++,sum^=x; rt[n+1]=++tot; build(rt[n+1],rt[n],24,sum); } } return 0; }