<题目链接>

题目大意:
给定一个序列,现在求出两段不相交的区间异或和的最大值。

解题分析:

区间异或问题首先想到01字典树。利用前缀、后缀建树,并且利用异或的性质,相同的两个数异或变成0,从而将前缀操作转化为区间操作,比如:$(a_1 \oplus a_2)\oplus(a_1 \oplus a_2 \oplus a_3 \oplus a_4) = a_3 \oplus a_4$。然后利用简单的$dp$,$predp[i]$记录前$[1~i]$ 任意区间的区间异或最大值(注意不是前缀),$nxtdp$同理记录后缀区间的最大值。

本题空间卡得比较紧,所以没有另外用一个$val[now]$数组记录Trie树前缀节点所表示的值,而是在$query$中用$ans$代替。

#include <bits/stdc++.h>
using namespace std; const int N = 4e5+;
typedef long long ll;
ll n,pos=,arr[N],nxt[N*][],predp[N],nxtdp[N]; template<typename T>
inline T read(T&x) {
x = ;int f = ; char ch = getchar();
while(ch<'' || ch>'') { if(ch == '-') f=-; ch=getchar(); }
while(ch>='' && ch<='') { x=x*+ch-''; ch=getchar(); }
return x*f;
}
void Insert(ll x){
int now=;
for(int i=;i>=;i--){
int to=(x>>i)&;
if(!nxt[now][to])nxt[now][to]=++pos;
now=nxt[now][to];
}
}
ll query(ll x){
int now=;ll ans=;
for(int i=;i>=;i--){
int to=(x>>i)&;
if(nxt[now][to^])now=nxt[now][to^],ans+=(<<i); //因为最终异或得到的答案就是x中所不包含的数位
else now=nxt[now][to];
}
return ans;
//return x^val[now]; 因为本题空间卡得紧,所以就不能写成这种形式
}
int main(){
read(n);
for(int i=;i<=n;i++)read(arr[i]);
for(int cur=,i=;i<=n;i++){
Insert(cur^=arr[i]);
predp[i]=max(query(cur),predp[i-]); //因为一个数被异或两次等于0,所以这里利用Trie树的前缀操作来实现区间操作
}//得到 i 的前缀区间异或和的最大值
memset(nxt,,sizeof(nxt));
for(int cur=,i=n;i>=;i--){
Insert(cur^=arr[i]);
nxtdp[i]=max(query(cur),nxtdp[i+]);
}//得到 i 的后缀异或区间和的最大值
ll ans=-;
for(int i=;i<=n;i++)ans=max(ans,predp[i]+nxtdp[i]);
printf("%lld\n",ans);
}

2019-03-02

BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)的更多相关文章

  1. bzoj 4260: Codechef REBXOR (01 Trie)

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

  2. BZOJ 4260: Codechef REBXOR( trie )

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

  3. BZOJ 4260: Codechef REBXOR (trie树维护异或最大值)

    题意 分析 将区间异或和转化为前缀异或和.那么[L,R][L,R][L,R]的异或和就等于presum[R] xor presum[L−1]presum[R]\ xor \ presum[L-1]pr ...

  4. BZOJ 4260 Codechef REBXOR(字典树)

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

  5. bzoj 4260 Codechef REBXOR——trie树

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

  6. BZOJ 4260 Codechef REBXOR

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

  7. BZOJ 4260 Codechef REBXOR 01trie

    好题...开阔思路 把每个前缀异或和依次插入$01trie$,插之前找一个最优的(就是从高位向低位贪心,尽量走相反方向)看看能不能更新答案,此时相当于找到了区间右端点不超过某个点$r$的最大或和$f[ ...

  8. 【BZOJ】4260: Codechef REBXOR【Trie树】【前后缀异或最大】

    4260: Codechef REBXOR Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2218  Solved: 962[Submit][Stat ...

  9. [BZOJ4260] Codechef REBXOR (01字典树,异或前缀和)

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

随机推荐

  1. Synchronizing timer

    http://blog.csdn.net/zjq001x/article/details/53107159 集合点: 简单来理解一下,虽然我们的“性能测试”理解为“多用户并发测试”,但真正的并发是不存 ...

  2. python之dict与set实现原理之hash算法

    理解不透彻,下回分解 http://www.cnblogs.com/pengsixiong/p/5326893.html https://blog.csdn.net/zhao_crystal/arti ...

  3. Java的家庭记账本程序(F)

    日期:2019.2.17 博客期:034 星期日 我先配置了Android的相关环境,先试着做了Hello World的测试,但是却出现了很严重的问题,问题如下: Unable to get curr ...

  4. xpath 根据根节点找数据

  5. python - 发送html格式的邮件

    import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom ...

  6. map函数和reduce函数的区别

    ①从参数方面来讲:map()函数: map()包含两个参数,第一个是参数是一个函数,第二个是序列(列表或元组).其中,函数(即map的第一个参数位置的函数)可以接收一个或多个参数.reduce()函数 ...

  7. ?:,reverse,vector的基本小结

    #include <cstdio> //此代码为网上所复制 #include <iostream> #include <string> #include <s ...

  8. 古代猪文:数论大集合:欧拉定理,exgcd,china,逆元,Lucas定理应用

    /* 古代猪文:Lucas定理+中国剩余定理 999911658=2*3*4679*35617 Lucas定理:(m,n)=(sp,tp)(r,q) %p 中国剩余定理:x=sum{si*Mi*ti} ...

  9. cf842D 01字典树|线段树 模板见hdu4825

    一般异或问题都可以转换成字典树的问题,,我一开始的想法有点小问题,改一下就好了 下面的代码是逆向建树的,数据量大就不行 /*3 01字典树 根据异或性质,a1!=a2 ==> a1^x1^..^ ...

  10. DOBRI

    问题 : DOBRI 时间限制: 1 Sec  内存限制: 128 MB 题目描述 给出一个包含N个整数的序列A,定义这个序列A的前缀和数组为SUM数组 ,当SUM数组中的第i个元素等于在i前面的三个 ...