题意

分析

将区间异或和转化为前缀异或和.那么[L,R][L,R][L,R]的异或和就等于presum[R] xor presum[L−1]presum[R]\ xor \ presum[L-1]presum[R] xor presum[L−1].所以相当于求presum[l1] xor presum[r1] + presum[l2] xor presum[r2]presum[l1]\ xor \ presum[r1]\ +\ presum[l2]\ xor \ presum[r2]presum[l1] xor presum[r1] + presum[l2] xor presum[r2]的最大值.这里0≤l1&lt;r1≤l2&lt;r2≤N0\le l1&lt;r1\le l2&lt;r2\le N0≤l1<r1≤l2<r2≤N.那么我们只要算出前缀两两异或最大值和后缀两两异或最大值,枚举每一个位置,然后把lmx[i]+rmx[i+1]lmx[i]+rmx[i+1]lmx[i]+rmx[i+1]取最大值就得到了答案.那怎么求这个前后缀两两异或最大值呢?拿lmxlmxlmx举例,有lmx[i]=Max{ lmx[i−1], Max0≤j&lt;i{presum[i] xor presum[j]} }lmx[i]=Max\{\ lmx[i-1], \ {Max}_{0\le j&lt;i}\{presum[i]\ xor\ presum[j]\}\ \}lmx[i]=Max{ lmx[i−1], Max0≤j<i​{presum[i] xor presum[j]} }求presum[i]presum[i]presum[i]异或上前面所有的值得到的最大值可以用0-1trie树来做.考虑贪心的策略.首先一定要让最高位尽量为1,那么就在trie树上跑,如果当前值xxx在这一位上位1,那么就优先往0那边走,如果xxx当前值为0,那么就优先往1那边走.优先的意思是如果此位置不为空就往下走,并加上对应贡献,否则走另一边,不加贡献.此时另一边不可能也为空,因为我们是把所有数看作长度为30的0-1串插入trie树,那么选一条路往下走一定能走到深度为30的点(也就是最底端).

Upd:Upd:Upd: 注意要提前insert一个0,否则hack数据(2 1 1),答案应该是2,而不insert 0答案是1.(被hack的幽怨)

CODE

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template<typename T>inline void read(T &num) {
char ch; int flg = 1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int MAXN = 400005;
int n, x[MAXN], l[MAXN];
struct Trie {
int ch[MAXN<<5][2], tot;
inline void clear() { memset(ch, 0, sizeof ch); tot = 0; }
inline void insert(int x) {
int r = 0, i;
for(int bit = 1<<30; bit; r = ch[r][i], bit>>=1)
if(!ch[r][i=(x&bit)?1:0]) ch[r][i] = ++tot;
}
inline int calc(int x) {
int r = 0, i, res = 0;
for(int bit = 1<<30; bit; bit>>=1)
if(ch[r][i=(x&bit)?0:1]) res += bit, r = ch[r][i];
else r = ch[r][i^1];
return res;
}
}T;
int main () {
read(n);
int sum = 0, ans = 0, R = 0;
T.insert(0);
for(int i = 1; i <= n; ++i) {
read(x[i]), sum ^= x[i];
l[i] = max(l[i-1], T.calc(sum));
T.insert(sum);
}
sum = 0; T.clear(); T.insert(0);
for(int i = n; i >= 1; --i) {
sum ^= x[i];
R = max(R, T.calc(sum));
T.insert(sum);
ans = max(ans, R + l[i]); //注意这里是i不是i-1,因为L位置与R位置异或起来表示的是[L+1,R]的异或和
//也就是说此处的R其实算的是[i+1,n]的区间异或和最大值
}
printf("%d\n", ans);
}

BZOJ 4260: Codechef REBXOR (trie树维护异或最大值)的更多相关文章

  1. bzoj 4260 Codechef REBXOR——trie树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4260 一段的异或和就是两个前缀的异或和.正反扫两边,用trie树算每个位置为左/右端点时最大 ...

  2. BZOJ 4260: Codechef REBXOR( trie )

    求出前缀和, 那么以第x个元素结尾的最大异或值是max(sumx^sump)(1≤p<x), 用trie加速. 后缀同理, 然后扫一遍就OK了.时间复杂度O(31N) ------------- ...

  3. bzoj 4260: Codechef REBXOR (01 Trie)

    链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4260 题面: 4260: Codechef REBXOR Time Limit: 10 S ...

  4. 【BZOJ4260】Codechef REBXOR Trie树+贪心

    [BZOJ4260]Codechef REBXOR Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. Output ...

  5. BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)

    <题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0, ...

  6. BZOJ 4260 Codechef REBXOR(字典树)

    [题目链接]  http://www.lydsy.com/JudgeOnline/problem.php?id=4260 [题目大意] 给出一个数列,请找出两段连续且不相交的数段,使得其分别异或和的和 ...

  7. BZOJ 4260 Codechef REBXOR

    Description Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. Output 输出一行包含给定表达式可能的最大值. Sample ...

  8. 【bzoj4260】Codechef REBXOR Trie树

    题目描述 输入 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN. 输出 输出一行包含给定表达式可能的最大值. 样例输入 5 1 2 3 1 2 样例输出 ...

  9. 【bzoj4260】 Codechef REBXOR trie树

    Input 输入数据的第一行包含一个整数N,表示数组中的元素个数. 第二行包含N个整数A1,A2,…,AN.     Output 输出一行包含给定表达式可能的最大值.   Sample Input ...

随机推荐

  1. HTML5页面如何在手机端浏览器调用相机、相册功能

    最近在做一个公司的保险信息处理系统项目,开发微信端浏览器访问的HTML5的页面,页面中有一个<input id="input" type="file"/& ...

  2. 对Python中print函数参数的认识

    输出函数是最常用的,对print()参数的准确认识尤为重要. sep='':sep参数表示函数中不同value的分隔符,默认为一个空格. end='':end参数表示函数结尾的处理,默认换行. 例如: ...

  3. python 分支语句 等值判断 逻辑运算符

    # 分支语句age = 233if age < 18: print('您还未满18岁,禁止入内')elif age > 18 and age < 60: print("欢迎 ...

  4. 以太坊再爆高危漏洞!黑客增发ATN 1100万枚token事件始末

    事情发生在5月中旬,ATN技术人员发现Token合约由于存在漏洞受到攻击.不过ATN基金会随后透露,将销毁1100万个ATN,并恢复ATN总量,同时将在主链上线映射时对黑客地址内的资产予以剔除,确保原 ...

  5. Java并发与多线程教程(3)

    Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...

  6. python 识别图像主题并切割

    两种办法,一种是用百度的API,效果还可以,不过好像每天有50次的调用的限制 from aip import AipImageClassify import cv2 """ ...

  7. Ocelot + Consul的demo

    参考大佬的博客写的:https://www.cnblogs.com/alan-lin/p/9126155.html:也可以参考这篇博客:https://www.cnblogs.com/axzxs200 ...

  8. luogu1313计算系数题解--二项式定理

    题目链接 https://www.luogu.org/problemnew/show/P1313 分析 二项式定理 \((a+b)^n=\sum_{k=0}^{n}{C^k_n a^k b^{n-k} ...

  9. 修改jumpserver源码并且实现一个自定义功能模块

    在前面已经说了,如何打开jumpserver的管理控制台并且自定义自己的数据模型.接下来实现一个自定义的功能模块. 先看效果! 一 定义好自己的模型(model) 1.1 这一块儿在前一篇博文已经讲过 ...

  10. C# 一个数组集合,任意组合,不遗漏,不重复

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...