【BZOJ3166】ALO(主席樹)
阿新 • • 發佈:2018-07-05
cst 持久 tdi read lib bzoj mat modify --
【BZOJ3166】ALO(主席樹)
題面
權限題qwq
資磁洛谷
題解
用一個\(set\)求出左右側比這個數大的第\(2\)個數,
然後用可持久化\(Trie\)算一下就好啦
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> using namespace std; #define ll long long #define RG register #define MAX 55555 inline int read() { RG int x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } set<int> S; set<int>::iterator it; int n,a[MAX],ans; int L[MAX],R[MAX]; struct Node{int ch[2],v;}t[MAX<<5]; int rt[MAX],tot; void Modify(int &x,int w,int p) { t[++tot]=t[x];x=tot;t[x].v++; if(p==-1)return; int c=(bool)(w&(1<<p)); Modify(t[x].ch[c],w,p-1); } int Query(int A,int B,int w,int p) { if(p==-1)return 0; int c=(bool)(w&(1<<p)); if(t[t[B].ch[c^1]].v-t[t[A].ch[c^1]].v) return Query(t[A].ch[c^1],t[B].ch[c^1],w,p-1)|(1<<p); return Query(t[A].ch[c],t[B].ch[c],w,p-1); } int Getl(int i) { it=S.find(i); if(it==S.begin())return 0;--it; if(it==S.begin())return 0;--it; return *it; } int Getr(int i) { it=S.find(i); ++it;if(it==S.end())return n+1; ++it;if(it==S.end())return n+1; return *it; } bool cmp(int x,int y){return a[x]>a[y];} int p[MAX]; int main() { n=read(); for(int i=1;i<=n;++i)a[i]=read(),p[i]=i; sort(&p[1],&p[n+1],cmp); for(int i=1;i<=n;++i) { S.insert(p[i]); L[p[i]]=Getl(p[i]); R[p[i]]=Getr(p[i]); } for(int i=1;i<=n;++i)rt[i]=rt[i-1],Modify(rt[i],a[i],31); for(int i=1;i<=n;++i) { if(i==p[1])continue; int l=L[i]+1,r=R[i]-1; ans=max(ans,Query(rt[l-1],rt[r],a[i],31)); } printf("%d\n",ans); return 0; }
【BZOJ3166】ALO(主席樹)