可持久化Trie+set
Orz zyf……
搞区间中次大值不好搞,那么我们就反过来,找一个数,然后看它在哪些区间里是次大值……
(然而事实上我们并不用真的把这个区间具体是什么找见,只要知道它可以跟哪一段数搞Xor就可以了!
而这个区间就是……左边第二个比他大的数的位置+1 ~ 右边第二个比它大的数的位置-1
这中间所有数都可以跟它搞Xor= =,我们总能找到一个相应的区间……
(我一开始理解成,这个区间就是我们要找的,a[i]为次大数的区间,然而这不是左边有一个比它大的,右边也有一个比它大的吗?但事实上我们是直接找了能跟a[i]搞Xor的区间(并)……
1 /************************************************************** 2 Problem: 3166 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:796 ms 7 Memory:28112 kb 8 ****************************************************************/ 9 10 //BZOJ 316611 #include12 #include 13 #include 14 #include 15 #include 16 #include 17 #define rep(i,n) for(int i=0;i =n;--i)20 #define pb push_back21 using namespace std;22 typedef long long LL;23 inline int getint(){24 int r=1,v=0; char ch=getchar();25 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;26 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;27 return r*v;28 }29 const int N=100010,M=2000010;30 /*******************template********************/31 32 int n,mx,a[N],t[M][2],rt[N],id[M],tot;33 set s;34 set ::iterator it;35 typedef pair pii;36 pii b[N];37 int l[N],r[N];38 39 inline void Ins(int pre,int x,int k){40 int now=rt[k]=++tot; id[tot]=k;41 D(i,30,0){42 int j=(x>>i)&1;43 t[now][j^1]=t[pre][j^1];44 t[now][j]=++tot; id[tot]=k;45 now=tot;46 pre=t[pre][j];47 }48 }49 inline int query(int l,int r,int x){50 int ans=0,now=rt[r];51 D(i,30,0){52 int j=((x>>i)&1)^1;53 if (id[t[now][j]]>=l) ans|=1<
3166: [Heoi2013]Alo
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 524 Solved: 262[][][]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
输出一行一个整数,表示最大能生成的宝石能量密度。