Description
Welcome to ALO ( Arithmetic and Logistic Online)。这是一个VR MMORPG ,
如名字所见,到处充满了数学的谜题。
现在你拥有n颗宝石,每颗宝石有一个能量密度,记为ai,这些宝石的能量
密度两两不同。现在你可以选取连续的一些宝石(必须多于一个)进行融合,设为 ai, ai+1, …, a j,则融合而成的宝石的能量密度为这些宝石中能量密度的次大值
与其他任意一颗宝石的能量密度按位异或的值,即,设该段宝石能量密度次大值
为k,则生成的宝石的能量密度为max{k xor ap | ap ≠ k , i ≤ p ≤ j}。
现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最大。
Input
第一行,一个整数 n,表示宝石个数。
第二行, n个整数,分别表示a1至an,表示每颗宝石的能量密度,保证对于i ≠ j有 ai ≠ aj。
Output
输出一行一个整数,表示最大能生成的宝石能量密度。
Sample Input
5
9 2 1 4 7
9 2 1 4 7
Sample Output
14
可以枚举次大值,那么它能覆盖的范围如图。
红色为枚举到的次大值,黑色为大于它的值,其余为小于它的值。
它做多能覆盖的两个区间如图。
这要在这些区间中查询即可。
对权值排序完后用set维护就好了。#include <stdio.h> #include <cstring> #include <set> #include <iostream> #include <algorithm> using namespace std; const int inf = 1<<30; const int MAXN = 50005; int n,Ans; std::set<int>q; template<typename _t> inline _t read(){ _t x=0,f=1; char ch=getchar(); for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48); return x*f; } struct data{ int pos,val; bool operator < (const data &a)const{ return val>a.val; } }a[MAXN]; struct Tree{ Tree *ch[2];int s; void* operator new(size_t,Tree *ls,Tree *rs,int size); }*null,*mempool,*C,*root[MAXN]; void* Tree :: operator new(size_t,Tree *ls,Tree *rs,int size){ if(C==mempool){ C=new Tree[1<<15]; mempool=C+(1<<15); } C->ch[0]=ls;C->ch[1]=rs;C->s=size; return C++; } Tree* insert(Tree *old,int x,int full=inf){ if(!full)return new(old->ch[0],old->ch[1],old->s+1)Tree; else if(x&full)return new(old->ch[0],insert(old->ch[1],x,full>>1),old->s+1)Tree; else return new(insert(old->ch[0],x,full>>1),old->ch[1],old->s+1)Tree; } int Query(Tree *old,Tree *now,int x,int full=inf){ if(!full)return 0; int d = (x&full)?0:1; int tmp = now->ch[d]->s-old->ch[d]->s; if(tmp)return full|Query(old->ch[d],now->ch[d],x,full>>1); else return Query(old->ch[d^1],now->ch[d^1],x,full>>1); } int main(){ n=read<int>(); null = new(null,null,0)Tree; null->ch[0]=null->ch[1]=null; root[0]=insert(null,0); for(int i=1;i<=n;i++){ a[i].val=read<int>(); a[i].pos=i; root[i]=insert(root[i-1],a[i].val); } std::sort(&a[1],&a[n+1]); q.insert(-1);q.insert(-2);q.insert(-3); q.insert(n+1);q.insert(n+2);q.insert(n+3); q.insert(a[1].pos); for(int i=2;i<=n;i++){ std::set<int>::iterator front,back; back=q.lower_bound(a[i].pos);front=back; back++; front--;front--; int l = *front+1,r=*back-1; l=max(l,1),r=min(r,n); Ans=max(Ans,Query(root[l-1],root[r],a[i].val)); q.insert(a[i].pos); } printf("%d\n",Ans); }
来源:https://www.cnblogs.com/Cooook/p/7738493.html