题面

Description

给定一个含N个元素的数组A,下标从1开始。请找出下面式子的最大值。

(A[l1]xorA[l2+1]xor…xorA[r1])+(A[l2]xorA[l2+1]xor…xorA[r2])

1<=l1<=r1<l2<=r2<=N

Input

输入数据的第一行包含一个整数N,表示数组中的元素个数。

第二行包含N个整数A1,A2,…,AN。

Output

输出一行包含给定表达式可能的最大值。

Sample Input

5
1 2 3 1 2

Sample Output

6

HINT

满足条件的(l1,r1,l2,r2)有:(1,2,3,3),(1,2,4,5),(3,3,4,5)。

对于100%的数据,2 ≤ N ≤ 4*105,0 ≤ Ai ≤ 109。

题目大意

找出两个有序数对\((L_1, R_1)\), \((L_2, R_2)\)满足\(L_1 <= R_1 < L_2 <= R_2\), 使得\(\oplus_{i = L_1}^{R_1} a_i + \oplus_{i = L_2}^{R_2}\)又最大值. 求这个最大值.

题解

我们先求出前缀异或和\(\{A_n = \oplus_{i = 1}^n a_i\}\), 则\(\oplus_{i = L}^R a_i = A_R \oplus A_{L - 1}\). 对于每一个右端点\(A_i\), 我们可以在trie上找到最大的\(A_j : j < i\)使得\(A_i \oplus A_j\)有最大值.

我们把序列反过来从右到左同样方法跑一次, 就能得到以某个位置为分界, 左边取一段异或和, 右边取一段异或和可以得到的最大值.

#include <cstdio>
#include <cctype>
#include <algorithm> const int N = (int)4e5; namespace Zeonfai
{
inline int getInt()
{
int a = 0, sgn = 1;
char c;
while(! isdigit(c = getchar()))
if(c == '-')
sgn *= -1;
while(isdigit(c))
a = a * 10 + c - '0', c = getchar();
return a * sgn;
}
} struct trieTree
{
struct node
{
node *suc[2]; inline node()
{
suc[0] = suc[1] = NULL;
}
}; node *rt; inline void insert(int w)
{
node *u = rt;
for(int i = 30; ~ i; -- i)
{
int k = w >> i & 1;
if(u->suc[k] == NULL)
u->suc[k] = new node;
u = u->suc[k];
}
} void Delete(node *u)
{
for(int i = 0; i < 2; ++ i)
if(u->suc[i] != NULL)
Delete(u->suc[i]);
delete u;
} inline void clear()
{
if(rt != NULL)
Delete(rt);
rt = new node();
insert(0);
} inline int query(int w)
{
int res = 0;
node *u = rt;
for(int i = 30; ~ i; -- i)
{
int k = w >> i & 1;
if(u->suc[k ^ 1] == NULL)
u = u->suc[k];
else
u = u->suc[k ^ 1], res |= 1 << i;
}
return res;
}
}trie; int main()
{
#ifndef ONLINE_JUDGE
freopen("REBXOR.in", "r", stdin);
#endif
using namespace Zeonfai;
int n = getInt();
static int a[N];
for(int i = 0; i < n; ++ i)
a[i] = getInt();
static int A[N];
A[0] = a[0];
for(int i = 1; i < n; ++ i)
A[i] = A[i - 1] ^ a[i];
static int mx[N][2];
trie.clear();
for(int i = 0; i < n; ++ i)
mx[i][0] = trie.query(A[i]), trie.insert(A[i]);
for(int i = 1; i < n; ++ i)
mx[i][0] = std::max(mx[i][0], mx[i - 1][0]);
A[n - 1] = a[n - 1];
for(int i = n - 2; ~ i; -- i)
A[i] = A[i + 1] ^ a[i];
trie.clear();
for(int i = n - 1; ~ i; -- i)
mx[i][1] = trie.query(A[i]), trie.insert(A[i]);
for(int i = n - 2; ~ i; -- i)
mx[i][1] = std::max(mx[i][1], mx[i + 1][1]);
int ans = 0;
for(int i = 0; i < n; ++ i)
ans = std::max(ans, mx[i][0] + mx[i][1]);
printf("%d\n", ans);
}

最新文章

  1. 关于《Linux.NET学习手记(8)》的补充说明
  2. 使用Spring发送带附件的电子邮件(站内和站外传送)
  3. Cube Processing Options
  4. 移动安全时代,如何保护你的app
  5. Android项目实战(十二):解决OOM的一种偷懒又有效的办法
  6. 【Linux】Mutex互斥量线程同步的例子
  7. 常见sql语句及复杂sql语句记录
  8. php 特定类型测试函数
  9. Luogu P5279 [ZJOI2019]麻将
  10. 我的那些年(9)~我来团队了,Mvc兴起了
  11. 20175212童皓桢 《Java程序设计》第六周学习总结
  12. 异常--finally关键字
  13. jvm 年轻代、年老代、永久代
  14. 简单JQuery+AJAX+Servlet的计算器实现
  15. NOIP 2000 乘积最大
  16. Linux命令 free:查看内存使用情况
  17. 使用ABP框架踩过的坑系列1
  18. Codeforces1151E,F | 553Div2 | 瞎讲报告
  19. html页面禁止选择复制剪切
  20. EF – 7.一对多关联

热门文章

  1. w3resource_MySQL练习: Aggregate_functions
  2. LeetCode(23)Merge k Sorted Lists
  3. istio的原理和功能介绍
  4. Python之code对象与pyc文件(一)
  5. python面试题解析(python基础篇80题)
  6. OpenSSL SNI
  7. Linux IP怎么设置
  8. springmvc始终跳转至首页,不报404错误
  9. 简单使用EL进行标签的替换
  10. 关于css的float