BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】
2018-04-25 18:20
746 查看
题目
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}。
现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最大。
输入格式
第一行,一个整数 n,表示宝石个数。
第二行, n个整数,分别表示a1至an,表示每颗宝石的能量密度,保证对于i ≠ j有 ai ≠ aj。
输出格式
输出一行一个整数,表示最大能生成的宝石能量密度。
输入样例
5
9 2 1 4 7
输出样例
14
提示
【样例解释】
选择区间[1,5],最大值为 7 xor 9。
对于 100%的数据有 1 ≤ n ≤ 50000, 0 ≤ ai ≤ 10^9
题解
我们枚举那个次大值的位置,然后我们找的可操作区间肯定是越大越好
然后用二分 + ST表找出最大的区间使得它为这个区间的最大值
要成为次大值,就跨过其中一个区间端点即可
然后就可以在可持久化trie树上询问答案了
注意区间边界的处理细节
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define LL long long int #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts(""); using namespace std; const int maxn = 50005,B = 30,maxm = 100005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int n,Log[maxn],bin[40],A[maxn],mx[maxn][17]; struct trie{ int ch[maxn * 35][2],sum[maxn * 35],rt[maxn],cnt; int ins(int r,int x){ int tmp,u; tmp = u = ++cnt; for (int i = B; i >= 0; i--){ ch[u][0] = ch[r][0]; ch[u][1] = ch[r][1]; sum[u] = sum[r] + 1; int t = x & bin[i]; t >>= i; r = ch[r][t]; u = ch[u][t] = ++cnt; } sum[u] = sum[r] + 1; return tmp; } int query(int u,int v,int x,int dep){ if (dep < 0) return 0; LL t = x & bin[dep]; t >>= dep; if (sum[ch[u][t ^ 1]] - sum[ch[v][t ^ 1]]) return bin[dep] + query(ch[u][t ^ 1],ch[v][t ^ 1],x,dep - 1); return query(ch[u][t],ch[v][t],x,dep - 1); } }T; int getmx(int l,int r){ int t = Log[r - l + 1]; return max(mx[l][t],mx[r - bin[t] + 1][t]); } void init(){ bin[0] = 1; REP(i,35) bin[i] = bin[i - 1] << 1; Log[0] = -1; for (int i = 1; i < maxn; i++) Log[i] = Log[i >> 1] + 1; n = read(); REP(i,n){ mx[i][0] = A[i] = read(); T.rt[i] = T.ins(T.rt[i - 1],A[i]); } REP(j,16) REP(i,n){ if (i + bin[j] - 1 > n) break; mx[i][j] = max(mx[i][j - 1],mx[i + bin[j - 1]][j - 1]); } } void solve(){ int l,r,mid,L,R,ans = 0; for (int i = 1; i <= n; i++){ if (i == 1 || A[i - 1] >= A[i]) L = i; else { l = 0; r = i - 1; while (l < r){ mid = l + r + 1 >> 1; if (getmx(i - mid,i - 1) < A[i]) l = mid; else r = mid - 1; } L = i - l; } if (i == n || A[i + 1] >= A[i]) R = i; else { l = 0; r = n - i; while (l < r){ mid = l + r + 1 >> 1; if (getmx(i + 1,i + mid) < A[i]) l = mid; else r = mid - 1; } R = i + l; } if (L == 1 && R == n) continue; if (R < n){ int tmp = R; R++; if (R == n || A[R + 1] >= A[i]) l = 0; else { l = 0; r = n - R; while (l < r){ mid = l + r + 1 >> 1; if (getmx(R + 1,R + mid) < A[i]) l = mid; else r = mid - 1; } R += l; } if (L < R) ans = max(ans,T.query(T.rt[R],T.rt[L - 1],A[i],B)); R = tmp; } if (L > 1){ L--; if (L == 1 || A[L - 1] >= A[i]) l = 0; else { l = 0; r = L - 1; while (l < r){ mid = l + r + 1 >> 1; if (getmx(L - mid,L - 1) < A[i]) l = mid; else r = mid - 1; } L -= l; } if (L < R) ans = max(ans,T.query(T.rt[R],T.rt[L - 1],A[i],B)); } } printf("%d\n",ans); } int main(){ init(); solve(); return 0; }
相关文章推荐
- BZOJ 3166 HEOI2013 Alo 可持久化Trie树
- [BZOJ3166][Heoi2013]Alo 可持久化Trie树
- 【BZOJ 3166】[Heoi2013]Alo 可持久化trie树+set
- 【BZOJ3166】[Heoi2013]Alo 可持久化Trie树+set
- 【bzoj3166】[Heoi2013]Alo 可持久化Trie树+STL-set
- BZOJ 3166: [Heoi2013]Alo|可持久化Trie树
- BZOJ 3166: [Heoi2013]Alo 可持久化字典树
- bzoj 3166 [Heoi2013]Alo 可持久化字典树
- [可持久化字典树 set] BZOJ 3166 [Heoi2013]Alo
- [BZOJ3166][HEOI2013]Alo-可持久化字典树
- BZOJ3166 [Heoi2013]Alo 可持久化Trie
- 【可持久化Trie】【set】bzoj3166 [Heoi2013]Alo
- BZOJ3166: [Heoi2013]Alo
- BZOJ 3166: [Heoi2013]Alo
- BZOJ3166: [Heoi2013]Alo
- bzoj 3166: [Heoi2013]Alo 可持久化trie
- [BZOJ3166][Heoi2013]Alo(可持久化线段树+可持久化tire树)
- 【bzoj3166】【HEOI2013】【Alo】【set+可持久化trie】
- BZOJ 3166: [Heoi2013]Alo
- BZOJ 3166 [Heoi2013]Alo