BZOJ 3166 [HEOI2013]Alo (可持久化01Trie+链表)
题目大意:给你一个长度为$n$的序列,让你找出一段子序列,求其中的 次大值 异或 序列里一个数 能得到的最大值
先对序列建出可持久化$Trie$
按元素的值从小到大遍历,设当前元素的位置是i,找出它左右离它最近第一个比$a_{i}$的位置$l1,r1$,再找出第二个比$a_{i}$大的位置$l2,r2$,这个可以用双向链表维护,保证$l1$和$r1$是$i$在链表里的$L_{i},R_{i}$
那么$a_{i}$能作为次大值出现的区间为$[l2+1,r1-1]$和$[l1+1,r2-1]$
把$a_{i}$放到可持久化$Trie$里,找出和上述区间内的数异或能得到的最大值
然后把$a_{i}$从链表内删除,因为$a_{i}$不会作为最大值影响后面的元素
1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 50100 8 #define N2 1600000 9 #define MM 100 10 #define ll long long 11 #define dd double 12 #define uint unsigned int 13 #define mod 1000000007 14 #define idx(X) (X-'a') 15 using namespace std; 16 17 int gint() 18 { 19 int ret=0,fh=1;char c=getchar(); 20 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 21 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 22 return ret*fh; 23 } 24 int bin[25]; 25 struct Trie{ 26 int ch[N2][2],num[N2],root[N1],tot; 27 void init() 28 { 29 tot=1;int x=1; 30 for(int i=29;i>=0;i--){ 31 ch[x][0]=++tot; 32 x=ch[x][0]; 33 num[x]=1; 34 } 35 } 36 void insert(int s,int rt1,int rt2,int w) 37 { 38 int x,y,p; 39 y=root[rt1]; 40 root[rt2]=++tot,x=root[rt2]; 41 for(int i=29;i>=0;i--){ 42 p=(s&bin[i])?1:0; 43 ch[x][p]=++tot; 44 ch[x][p^1]=ch[y][p^1]; 45 num[ch[x][p]]=num[ch[y][p]]+w; 46 x=ch[x][p],y=ch[y][p]; 47 } 48 } 49 uint query(int l,int r,uint s) 50 { 51 int x,y,p;uint ans=0; 52 x=root[r],y=l<0?0:root[l]; 53 for(int i=29;i>=0;i--){ 54 p=(s&bin[i])?1:0; 55 if(num[ch[x][p^1]]-num[ch[y][p^1]]>0){ 56 x=ch[x][p^1],y=ch[y][p^1]; 57 ans|=bin[i]; 58 }else if(num[ch[x][p]]-num[ch[y][p]]>0){ 59 x=ch[x][p],y=ch[y][p]; 60 }else break; 61 }return ans; 62 } 63 }T; 64 65 int n,m; 66 uint a[N1]; 67 int L[N1],R[N1]; 68 struct node{uint w;int id;}b[N1]; 69 int cmp(node s1,node s2){return s1.w<s2.w;} 70 71 int main() 72 { 73 //freopen("1.in","r",stdin); 74 scanf("%d",&n); 75 for(int i=0;i<=29;i++) 76 bin[i]=(1<<i); 77 T.init(); 78 for(int i=1;i<=n;i++){ 79 a[i]=gint(); 80 b[i].w=a[i],b[i].id=i; 81 T.insert(a[i],i-1,i,1); 82 L[i]=i-1,R[i]=i+1; 83 } 84 sort(b+1,b+n+1,cmp); 85 int l1,r1,l2,r2; 86 uint s1,s2,ans=0; 87 for(int j=1;j<=n;j++){ 88 int i=b[j].id; 89 l1=L[i],r1=R[i]; 90 l2=L[l1],r2=R[r1]; 91 s1=0,s2=0; 92 if(l1!=0) s1=T.query(l2,r1-1,a[i]); 93 if(r1!=n+1) s2=T.query(l1,r2-1,a[i]); 94 ans=max(ans,max(s1,s2)); 95 L[R[i]]=L[i],R[L[i]]=R[i]; 96 } 97 printf("%u\n",ans); 98 return 0; 99 }