给定一个非负整数序列{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 最大,输出最大是多少。
第一行包含两个整数 N ,M,含义如问题描述所示。
第二行包含 N个非负整数,表示初始的序列 A 。
接下来 M行,每行描述一个操作,格式如题面所述。
假设询问操作有 T个,则输出应该有 T行,每行一个整数表示询问的答案。
#include<bits/stdc++.h> using namespace std; const int maxn=3e5+15; int n,m,sz; int t[maxn<<5][2],sum[maxn<<5],b[maxn],q[maxn]; inline int read(){ char ch=getchar(); int s=0,f=1; while (!(ch>=‘0‘&&ch<=‘9‘)) {if (ch==‘-‘) f=-1;ch=getchar();} while (ch>=‘0‘&&ch<=‘9‘) {s=(s<<3)+(s<<1)+ch-‘0‘;ch=getchar();} return s*f; } int ins(int last,int val) { int res,k; res=k=++sz; for (int i=23;i>=0;i--) { sum[k]=sum[last]+1; t[k][0]=t[last][0];t[k][1]=t[last][1]; bool d=val&(1<<i); k=t[k][d]=++sz;last=t[last][d]; } sum[k]=sum[last]+1; return res; } int query(int k1,int k2,int val) { int res=0; for (int i=23;i>=0;i--) { bool d=val&(1<<i); if (sum[t[k2][d^1]]-sum[t[k1][d^1]]>0){ res|=(1<<i); k1=t[k1][d^1]; k2=t[k2][d^1]; } else k1=t[k1][d],k2=t[k2][d]; } return res; } int main() { n=read()+1;m=read(); q[1]=ins(q[0],b[1]); for (int i=2;i<=n;i++) { b[i]=b[i-1]^read();//注意插入trie的是前缀和 q[i]=ins(q[i-1],b[i]); } for (int i=1;i<=m;i++) { char ch=getchar(); while (!(ch==‘A‘||ch==‘Q‘)) ch=getchar(); if (ch==‘A‘) { ++n; b[n]=b[n-1]^read(); q[n]=ins(q[n-1],b[n]); } else { int l=read(),r=read(),x=read(); printf("%d\n",query(q[l-1],q[r],x^b[n])); } } return 0; }
原文:https://www.cnblogs.com/xxzh/p/9188295.html