Description



## 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。


Source

By yts1999


Solution

考虑几点:

  • 我们所选的区间不能相交。
  • 显而易见的贪心,我们所选的区间必须是区域内异或和最大的。

于是我们考虑用 01字典树 来求解。

我们可以很方便地处理出在一段区间内最大异或和的区间。

直接记录一遍异或前缀和,然后一个一个插入并查询即可。

但是由于不能选相交的区间,我们不能考虑直接选两个最大的区间。

可以考虑用一个数组:

\[f[maxn]
\]

用于储存前 \((1 , i )\) 区间的异或最大值。

那么我们记录完之后,直接从后面再开始一遍选最大区间。

我们从 \(n\) 枚举到 \(1\);

\[Ans=\max_{i=1}^n(Ans,f[i-1]+query(sub[i]))
\]

其中 \(sub\) 数组表示 \(n\) 到 \(i\) 异或后缀和。

如以上求解即可,时间复杂度 \(O(2*nlogn)\)。

不过这题需要注意以下空间不能开太大。


代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=400008;
  4. int c[maxn],f[maxn];
  5. int n,m,pre[maxn],sub[maxn];
  6. int ch[32*maxn][2];
  7. int val[32*maxn];
  8. int num[32*maxn];
  9. int sz,ans=-1;
  10. void init()
  11. {
  12. memset(ch[0],0,sizeof(ch[0]));
  13. sz=1;
  14. }
  15. void insert(int a)
  16. {
  17. int u=0;
  18. for(int i=32;i>=0;i--)
  19. {
  20. int c=((a>>i)&1);
  21. if(!ch[u][c])
  22. {
  23. memset(ch[sz],0,sizeof(ch[sz]));
  24. val[sz]=0;
  25. num[sz]=0;
  26. ch[u][c]=sz++;
  27. }
  28. u=ch[u][c];
  29. num[u]++;
  30. }
  31. val[u]=a;
  32. return;
  33. }
  34. int query(int x)
  35. {
  36. int u=0;
  37. for(int i=32;i>=0;i--)
  38. {
  39. int c=((x>>i)&1);
  40. if(ch[u][c^1]&&num[ch[u][c^1]])
  41. u=ch[u][c^1];
  42. else u=ch[u][c];
  43. }
  44. return x^val[u];
  45. }
  46. int main()
  47. {
  48. cin>>n;
  49. for(int i=1;i<=n;i++)
  50. scanf("%d",&c[i]);
  51. for(int i=1;i<=n;i++)
  52. pre[i]=pre[i-1]^c[i];
  53. for(int i=n;i>0;i--)
  54. sub[i]=sub[i+1]^c[i];
  55. for(int i=1;i<=n;i++)
  56. f[i]=max(f[i-1],query(pre[i])),
  57. insert(pre[i]);
  58. init(); insert(sub[n+1]);
  59. for(int i=n;i>0;i--)
  60. ans=max(ans,query(sub[i])+f[i-1]),
  61. insert(sub[i]);
  62. cout<<ans<<endl;
  63. return 0;
  64. }

[BZOJ4260] Codechef REBXOR (01字典树,异或前缀和)的更多相关文章

  1. P4551 最长异或路径 (01字典树,异或前缀和)

    题目描述 给定一棵 n 个点的带权树,结点下标从 1 开始到 N .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式: 第一行一 ...

  2. hdu 4825 && acdream 1063 01字典树异或问题

    题意: 给一个集合,多次询问,每次给一个k,问你集合和k异或结果最大的哪个 题解: 经典的01字典树问题,学习一哈. 把一个数字看成32位的01串,然后查找异或的时候不断的沿着^为1的路向下走即可 # ...

  3. [Bzoj4260]Codechef REBXOR(trie树)

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

  4. BZOJ 4260 Codechef REBXOR(字典树)

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

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

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

  6. 【BZOJ4260】Codechef REBXOR (Trie树)

    [BZOJ4260]Codechef REBXOR (Trie树) 题面 BZOJ 题解 两眼题.第一眼不会做,第二眼好简单... 前缀异或和一下,拿\(Trie\)树维护求一个在这个端点以左的最大值 ...

  7. Chip Factory---hdu5536(异或值最大,01字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k] ...

  8. AcWing:144. 最长异或值路径(dfs + 01字典树)

    给定一个树,树上的边都具有权值. 树中一条路径的异或长度被定义为路径上所有边的权值的异或和: ⊕ 为异或符号. 给定上述的具有n个节点的树,你能找到异或长度最大的路径吗? 输入格式 第一行包含整数n, ...

  9. AcWing:143. 最大异或对(01字典树 + 位运算 + 异或性质)

    在给定的N个整数A1,A2……ANA1,A2……AN中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N. 第二行输入N个整数A1A1-ANAN. 输出格式 输出一 ...

随机推荐

  1. css设置禁止文字被选中

    // 禁止文字被鼠标选中 moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-se ...

  2. BCB:使用CppWebBrowser判断网页加载完成

    void __fastcall TForm1::CppWebBrowser1DocumentComplete(TObject *Sender, LPDISPATCH pDisp, Variant *U ...

  3. oracle没有监听和监听程序无法找到适用于客户机连接的例程

    1.无监听,可以尝试下以下几种办法: 1)在net manager中重新配置监听.我的net manager监听点开不了,把ADMIN下的listener.ora删掉再去打开试试. 2)cmd中输入n ...

  4. Spinal Tap Case -freecodecamp算法题目

    Spinal Tap Case 1.要求 将字符串转换为 spinal case. Spinal case 是 all-lowercase-words-joined-by-dashes 这种形式的,也 ...

  5. 重温经典之赫夫曼(Huffman)编码

    先看看赫夫曼树假设有n个权值{w1,w2,…,wn},构造一个有n个叶子结点的二叉树,每个叶子结点权值为wi,则其中带权路径长度WPL最小的二叉树称作赫夫曼树或最优二叉树. 赫夫曼树的构造,赫夫曼最早 ...

  6. 主题模型LDA及在推荐系统中的应用

    1 关于主题模型 使用LDA做推荐已经有一段时间了,LDA的推导过程反复看过很多遍,今天有点理顺的感觉,就先写一版. 隐含狄利克雷分布简称LDA(latent dirichlet allocation ...

  7. Thinkphp 5 调试执行的SQL语句

    在模型操作中 ,为了更好的查明错误,经常需要查看下最近使用的SQL语句,我们可以用getLastsql方法来输出上次执行的sql语句.例如: User::get(1); echo User::getL ...

  8. Ubuntu 16.04系统安装步骤

    1.安装系统 2.设置更新源,自动检测最优更新源 3.关闭自动更新 4.设置终端样式 5.设置终端快捷键 6.安装vim,配置.vimrc 7.修改.bashrc第62行,小写w为大写W,设置终端不显 ...

  9. Manjaro 添加国内源和安装搜狗输入法

    Manjaro 系统虽然比 Ubuntu 用着稳定,但有些小地方没有 Ubuntu 人性化,比如默认安装完的系统貌似没有中国的,Ubuntu 估计是用的人多,所以安装完后会根据所在地给你配置更新的源. ...

  10. MySQL练习50题

    介绍一个学习SQL的网站:https://sqlbolt.com/ 习题来源于网络,SQL语句是自己的练习答案,部分参考了网络上的答案. 花了一晚上的时间做完,个人认为其中的难点有:分组提取前几名的数 ...