您的位置:首页 > 其它

【BZOJ 3166】[Heoi2013]Alo 可持久化trie树+set

2017-01-19 21:22 501 查看
看到异或最大值容易想到trie树,至于区间异或最大值的话,可持久化一下就可以搞了。

至于满足次大值那个。。。

倒序排序权值,然后把它们的坐标插入set中,每一次lower_bound后找前继的前继和后驱就好了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#define maxn 50010
#define inf 0x3fffffff
using namespace std;
set<int>s;
int n,ch[maxn*35][2],rt[maxn],bin[35],tot,size[maxn*35];
struct node{
int x,id;
bool operator<(const node& y)const{return x>y.x;}
}a[maxn];

int insert(int x,int val){
int root=++tot;int y=root;
for(int c,i=30;i>=0;i--){
c=(val>>i)&1;
ch[y][!c]=ch[x][!c];
y=ch[y][c]=++tot;
x=ch[x][c];
size[y]=size[x]+1;
}
return root;
}
int query(int l,int r,int val){
int ans=0;
for(int c,i=30;i>=0;i--){
c=(val>>i)&1;
if(size[ch[r][!c]]-size[ch[l][!c]])
r=ch[r][!c],l=ch[l][!c],ans=ans<<1|1;
else l=ch[l][c],r=ch[r][c],ans=ans<<1;
}
return ans;
}

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].x);a[i].id=i;
rt[i]=insert(rt[i-1],a[i].x);
}sort(a+1,a+1+n);
s.insert(-1),s.insert(inf);s.insert(a[1].id);
s.insert(inf+1),s.insert(-2);
set <int>::iterator l,r;
int ans=0,x,y;
for(int i=2;i<=n;i++){
l=r=s.lower_bound(a[i].id);
l--;l--;r++;
x=*l+1,y=*r-1;
x=max(1,x),y=min(y,n);
ans=max(ans,query(rt[x-1],rt[y],a[i].x));
s.insert(a[i].id);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: