LOJ

洛谷

考场上都拍上了,8:50才发现我读错了题=-=

两天都读错题...醉惹...


\(Solution1\)

先求一遍前缀异或和。

假设左端点是\(i\),那么我们要在\([i,n]\)中找一个\(sum_j\)使得它和\(sum_{i-1}\)异或最大。可以可持久化Trie。

对\(i\in[1,n]\)都求一遍它能得到的最大的异或值,扔到堆里。

每次从堆里找出值最大的,假设是\(x\),与\(sum_{x-1}\)异或得到最大值的数是\(sum_y\),那么之后就不能选\(sum_{x-1}\ \mathbb{xor}\ sum_y\)了。

记\(T_i\)为第\(i\)棵\(Trie\)。因为查询最大值时,我们是用\(T_n\)与\(T_{i-1}\)的\(size\)差是否\(>0\),来判断能否取一个值。

所以现在令\(T_{x-1}\)在\(sum_y\)这条路径上的\(size+1\),就可以实现删掉一个\(sum_y\)了。

修改\(T_{x-1}\)之后再找一个和\(sum_{x-1}\)异或最大的,把\(x\)扔到堆里。

这个\(Modify\)和\(Insert\)函数一模一样(考场上我竟然没注意到这个=-=)。

\(Solution2\)

\(sum_i\ ^{\wedge}sum_j=sum_j\ ^{\wedge}sum_i\),所以可以把\(k\)变成\(2k\),求任意一对数异或,能得到的最大的\(k\)对是多少。

对每个数求一下和它异或最大的是哪个,扔到堆里。

每次从堆里取出值最大的一个数\(i\),加上\(i\)的答案。然后我们要找,和\(sum_i\)异或第二大的值是哪个。在\(Trie\)上查即可。再扔到堆里。再下一次就查,和\(sum_i\)异或第\(3\)大的值是哪个...

对所有数建一棵\(Trie\)即可。

\(Solution3\)

有一种类似[NOI2010]超级钢琴的做法。


代码是考场上的代码,有点丑,但也没什么改的必要了...

  1. #include <queue>
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <cstring>
  5. #include <algorithm>
  6. //#include <unordered_map>
  7. #define mp std::make_pair
  8. #define pr std::pair<uint,int>
  9. #define BIT 31
  10. //#define gc() getchar()
  11. #define MAXIN 300000
  12. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  13. typedef unsigned int uint;
  14. typedef long long LL;
  15. typedef unsigned long long ull;
  16. const int N=5e5+5;
  17. int root[N];
  18. uint A[N],sum[N];
  19. std::priority_queue<pr> q;
  20. //std::mt19937 Rand(1002330);
  21. char IN[MAXIN],*SS=IN,*TT=IN;
  22. struct Trie
  23. {
  24. #define S N*(BIT+2)*2
  25. int tot,son[S][2],sz[S];
  26. void Insert(int &rt,int y,uint v)
  27. {
  28. int x=rt=++tot;
  29. for(int i=BIT; ~i; --i)
  30. {
  31. int c=v>>i&1;
  32. son[x][c^1]=son[y][c^1];
  33. x=son[x][c]=++tot, y=son[y][c], sz[x]=sz[y]+1;
  34. }
  35. }
  36. uint Query(int x,int y,uint v)//y-x
  37. {
  38. uint res=0;
  39. for(int i=BIT; ~i; --i)
  40. {
  41. int c=(v>>i&1)^1;
  42. if(sz[son[y][c]]-sz[son[x][c]]>0) res|=1u<<i;
  43. else c^=1;
  44. x=son[x][c], y=son[y][c];
  45. }
  46. return res;
  47. }
  48. void Modify(int &rt,int X,uint v)
  49. {
  50. int x=rt=++tot;
  51. for(int i=BIT; ~i; --i)
  52. {
  53. int c=(v>>i&1);
  54. son[x][c^1]=son[X][c^1];
  55. x=son[x][c]=++tot, X=son[X][c], sz[x]=sz[X]+1;
  56. }
  57. }
  58. }T;
  59. inline uint read()
  60. {
  61. uint now=0; register char c=gc();
  62. for(;!isdigit(c);c=gc());
  63. for(;isdigit(c);now=now*10+c-48,c=gc());
  64. return now;
  65. }
  66. namespace Subtask1
  67. {
  68. uint q[4000005];
  69. void Main(int n,int K)
  70. {
  71. int t=0;
  72. for(int i=1; i<=n; ++i)
  73. {
  74. uint now=0;
  75. for(int j=i; j<=n; ++j)
  76. now^=A[j], q[++t]=now;
  77. }
  78. std::sort(q+1,q+1+t,std::greater<uint>());
  79. LL ans=0;
  80. for(int i=1; i<=t&&i<=K; ++i) ans+=q[i];
  81. printf("%I64d\n",ans);
  82. }
  83. }
  84. int main()
  85. {
  86. freopen("xor.in","r",stdin);
  87. freopen("xor.out","w",stdout);
  88. int n=read(),K=read();
  89. for(int i=1; i<=n; ++i) A[i]=read(),sum[i]=A[i]^sum[i-1];
  90. // if(n<=2000) return Subtask1::Main(n,K),0;
  91. for(int i=1; i<=n; ++i) T.Insert(root[i],root[i-1],sum[i]);
  92. for(int i=1; i<=n; ++i) q.push(mp(T.Query(root[i-1],root[n],sum[i-1]),i));
  93. LL ans=0;
  94. while(K--&&!q.empty())
  95. {
  96. uint tmp=q.top().first; ans+=tmp;
  97. int x=q.top().second; q.pop();
  98. T.Modify(root[x-1],root[x-1],tmp^sum[x-1]);
  99. q.push(mp(T.Query(root[x-1],root[n],sum[x-1]),x));
  100. }
  101. printf("%I64d\n",ans);
  102. return 0;
  103. }

洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)的更多相关文章

  1. [十二省联考2019] 异或粽子 - 可持久化Trie,堆

    求 \(n\) 元数列的 \(k\) 个不同的子区间使得各个子区间异或和之和最大. Solution (差点又看错题了) 做个前缀和,于是转化成求序列异或和最大的 \(k\) 个数对 建一棵可持久化 ...

  2. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  3. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  4. 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)

    [BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...

  5. [十二省联考2019]异或粽子 01trie

    [十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和 ...

  6. 【简】题解 P5283 [十二省联考2019]异或粽子

    传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...

  7. 洛谷.5284.[十二省联考2019]字符串问题(后缀自动机 拓扑 DP)

    LOJ BZOJ 洛谷 对这题无话可说,确实比较...裸... 像dls说的拿拓扑和parent树一套就能出出来了... 另外表示BZOJ Rank1 tql... 暴力的话,由每个\(A_i\)向它 ...

  8. 洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解

    https://www.luogu.org/problemnew/show/P5283 https://loj.ac/problem/3048 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...

  9. Luogu P5283 / LOJ3048 【[十二省联考2019]异或粽子】

    联考Day1T1...一个考场上蠢了只想到\(O(n^2)\)复杂度的数据结构题 题目大意: 求前\(k\)大区间异或和的和 题目思路: 真的就是个sb数据结构题,可持久化01Trie能过(开O2). ...

随机推荐

  1. 洛谷P1258 小车问题(题解)

    https://www.luogu.org/problemnew/show/P1258(题目传送) 看题的第一眼就把题归为二分题,一直向着二分的方向走,却忽略了数学的推理.推理一番后(看了题解),发现 ...

  2. JSP总结(三)——JSP中九大内置对象(汇总)

    注:后缀为汇总的基本上是整理一些网上的. 一.九大内置对象分类: 1. request  请求对象 类型 javax.servlet.ServletRequest        作用域 Request ...

  3. Linux 配置vim编辑器

    最终效果 步骤1.下载NERDTree插件安装包(vim目录插件) https://www.vim.org/scripts/script.php?script_id=1658 步骤2.在家目录创建 . ...

  4. app升级注意事项version

    1.每次升级生成apk前,修改versionName: 位置: 2.修改数据库表中对应version字段与之对应: 3.出现waiting for debugger,要重启手机: 5.解析包错误,是a ...

  5. 验证性控件的使用--验证两个文本框至少有一个不为空CustomValidator

    转:http://blog.163.com/zhaowencong_2010/blog/static/20402815220122103155643/ 有时候我们在注册一个帐号时要求我们留下电话号码, ...

  6. javascript节点移除

    var itemdel = document.getElementById("test"); itemdel.removeChild(lis[0]); 兼容性较好 itemdel. ...

  7. [物理学与PDEs]第4章第3节 一维反应流体力学方程组 3.1 一维反应流体力学方程组

    1. 一维粘性热传导反应流体力学方程组 $$\beex \bea \cfrac{\p\rho}{\p t}&+\cfrac{\p}{\p x}(\rho u)=0,\\ \cfrac{\p}{ ...

  8. DUMP2 企业级电商项目

    正常设计数据库表,按照数据流向. ~~闭环核心业务 [1用户]登录 =>浏览[2分类]+浏览[3商品]=>加入[4购物车]=>结算[5订单]+[6收货地址]=>[7支付] [购 ...

  9. 在JS中如何判断所输入的是一个数、整数、正数、非数值?

    1.判断是否为一个数字: Number(num)不为 NaN,说明为数字 2. 判断一个数为正数: var num=prompt("请输入:"); if(Number(num)&g ...

  10. CSRF篇-本着就了解安全本质的想法,尽可能的用通俗易懂的语言去解释安全漏洞问题

    0x01 Brief Description csrf 跨站伪造请求,请求伪造的一种,是由客户端即用户浏览器发起的一种伪造攻击.攻击的本质是请求可以被预测的到. 在了解csrf攻击之前,需要了解浏览器 ...