http://www.lydsy.com/JudgeOnline/problem.php?id=3261php
給定一個非負整數序列{a},初始長度爲N。有M個操做,有如下兩種操做類型:一、A x:添加操做,表示在序列末尾添加一個數x,序列的長度N+1。二、Q l r x:詢問操做,你須要找到一個位置p,知足l<=p<=r,使得:a[p] xor a[p+1] xor ... xor a[N] xor x 最大,輸出最大是多少。
前置技能:HDU4825html
會了這個前置技能以後默認你會如何建trie跑貪心了。node
參考:http://www.javashuo.com/article/p-xsulolpw-mq.htmlios
對於一段區間的異或和=r的前綴異或和^l-1的前綴異或和。git
因此咱們處理出全部前綴異或和完後往trie上插。spa
不過因爲是區間詢問,因此按照主席樹(可持久化線段樹)的想法,咱們創建可持久化trie,具體的創建方法大體和主席樹差很少,就很少講了直接看代碼吧。code
至於詢問,咱們直接詢問哪一個前綴能和(n的前綴異或和^x)異或值最大便可。htm
直接引用參考博客:blog
若是 x (詢問數)的這一位爲 p ,那麼咱們查詢Sum[son[l][p ^ 1]] - Sum[son[r][p ^ 1],Sum爲節點上有多少的值。get
如若 表達式 > 0 那麼咱們就像 p ^ 1 的方向行走,同時 答案加上 1 << d 由於這一位被咱們錯開了。
不然只好向 p 的方向行走, 不加上 1 << d。
緣由請參考前置技能。
另外還要注意咱們查詢的內容自己就是前綴和,左端點和右端點就須要同時減一,同時查區間,那麼左端點就還須要須要減一。
參考裏提到了一個小技巧就是在最開始插一個0,這樣就不須要左端點和右端點同時減一了,否則本身看着怪難受的。
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #include<cctype> using namespace std; typedef long long ll; const int N=6e5+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } inline char getc(){ char ch=getchar(); while(ch!='A'&&ch!='Q')ch=getchar(); return ch; } struct node{ int son[2],sum; }tr[50*N]; int tot,b[N],rt[N],pool; void insert(int y,int &x,int k,int now){ tr[x=++pool]=tr[y]; tr[x].sum++; if(now<0)return; bool p=k&(1<<now); insert(tr[y].son[p],tr[x].son[p],k,now-1); return; } int query(int nl,int nr,int k,int now){ if(now<0)return 0; bool p=k&(1<<now); int delta=tr[tr[nr].son[p^1]].sum-tr[tr[nl].son[p^1]].sum; if(delta>0)return (1<<now)+query(tr[nl].son[p^1],tr[nr].son[p^1],k,now-1); else return query(tr[nl].son[p],tr[nr].son[p],k,now-1); } int main(){ int n=read()+1,m=read(); for(int i=2;i<=n;i++)b[i]=b[i-1]^read(); for(int i=1;i<=n;i++)insert(rt[i-1],rt[i],b[i],24); for(int i=1;i<=m;i++){ char ch=getc(); if(ch=='A'){ b[++n]=b[n-1]^read(); insert(rt[n-1],rt[n],b[n],24); }else{ int l=read(),r=read(),x=read(); printf("%d\n",query(rt[l-1],rt[r],b[n]^x,24)); } } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文做者:luyouqi233。 +
+歡迎訪問個人博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++