简要题意

其实我觉得这个部分可以不要,因为这道题的题面还是很清晰的。

你需要维护一个数据结构,支持区间异或和区间求与 \(v\) 的最大异或和。

思路

对于这种区间问题,最容易想到的就是 分块 线段树。

而对于复杂的异或问题,最容易想到的就是 01 Trie 线性基。

合在一起,就是线段是套线性基。(好像还用了顶针的手法)

做这道题之前建议先做 P4839 P哥的桶 那是这一道题的弱化版。

(现在默认大家已经做过P哥的桶了)

P哥的桶中,是单点修改,而这道题是区间修改,用传统的打tag是不方便维护的,我们可以用差分的思想。

Sol1大佬的文章已经有了正确性证明,我这里就口胡一下结论:

我们可以维护异或差分数组 \(b\),然后每次询问 \([l,r]\) 就在线段树上询问 \([l+1,r]\),再插入 \(a_l\) 即可。

然后就是一个差分的过程,随便找一个数据结构维护一下即可。(这里是树状数组)

细节

(由于没特判 \(l=r\) \(45\) 分挂了很久)

注意要特判 \(l=r\),如果 \(l=r\),那么就可以分类讨论一下,答案就是 \(\max\{\operatorname{BIT.query}(l) \operatorname{xor} v,v\}\)。

下面代码的注释也有说明(虽然是蹩脚的英文的)

代码

(纪念,这是我A的第二道Ynoi,也是第一篇试图提交题解的Ynoi)

里面有一份线性基模板,如果您觉得我的代码好,可以参考。

不用卡常,好耶!

  1. #include <bits/stdc++.h>
  2. #define int long long
  3. using namespace std;
  4. namespace Basis{
  5. const int MAX_BIT = 30;
  6. struct Basis{
  7. int p[MAX_BIT+5];
  8. int _how_many_numbers_can_xor;
  9. void clear(){
  10. memset(p,0,sizeof(p));
  11. _how_many_numbers_can_xor=0;
  12. }
  13. Basis(){
  14. clear();
  15. }
  16. void insert(int x){
  17. for(int i=MAX_BIT;i>=0;i--){
  18. if(!(x&(1ll<<i)))continue;
  19. if(!p[i]){
  20. p[i]=x;
  21. _how_many_numbers_can_xor++;
  22. break;
  23. }
  24. x^=p[i];
  25. }
  26. }
  27. int max_xor(int init=0){
  28. int ans=init;
  29. for(int i=MAX_BIT;i>=0;i--){
  30. if((ans^p[i])>ans){
  31. ans^=p[i];
  32. }
  33. }
  34. return ans;
  35. }
  36. bool can_be_xor(int x){
  37. for(int i=MAX_BIT;i>=0;i--){
  38. if(x&(1ll<<i))x^=p[i];
  39. }
  40. return x==0;
  41. }
  42. int numbers_can_xor(){
  43. return (1ll<<_how_many_numbers_can_xor);
  44. }
  45. void expand(Basis &x){
  46. for(int i=MAX_BIT;i>=0;i--){
  47. if(x.p[i]){
  48. insert(x.p[i]);
  49. }
  50. }
  51. }
  52. };
  53. Basis merge(Basis x,Basis y){
  54. for(int i=MAX_BIT;i>=0;i--){
  55. if(y.p[i])x.insert(y.p[i]);
  56. }
  57. return x;
  58. }
  59. }
  60. int n,m;
  61. int a[50005];
  62. namespace sgt{
  63. Basis::Basis t[200005];
  64. void pushup(int i){
  65. t[i]=Basis::merge(t[i<<1],t[i<<1|1]);
  66. }
  67. void build(int i,int l,int r){
  68. for(int ii=l;ii<=r;ii++){
  69. t[i].insert(a[ii]);
  70. }
  71. if(l==r){
  72. return;
  73. }
  74. int mid=(l+r)>>1;
  75. build(i<<1,l,mid);
  76. build(i<<1|1,mid+1,r);
  77. pushup(i);
  78. }
  79. void update(int x,int v,int i,int l,int r){
  80. if(l==r){
  81. t[i].clear();
  82. a[l]^=v;
  83. t[i].insert(a[l]);
  84. return;
  85. }
  86. int mid=(l+r)>>1;
  87. if(x<=mid){
  88. update(x,v,i<<1,l,mid);
  89. }
  90. else{
  91. update(x,v,i<<1|1,mid+1,r);
  92. }
  93. pushup(i);
  94. }
  95. Basis::Basis query(int ql,int qr,int i,int l,int r){
  96. if(ql<=l&&r<=qr){
  97. return t[i];
  98. }
  99. Basis::Basis result;
  100. int mid=(l+r)>>1;
  101. if(ql<=mid){
  102. result=merge(result,query(ql,qr,i<<1,l,mid));
  103. }
  104. if(qr>mid){
  105. result=merge(result,query(ql,qr,i<<1|1,mid+1,r));
  106. }
  107. return result;
  108. }
  109. }
  110. namespace BIT{
  111. int t[50005];
  112. void clear(){
  113. memset(t,0,sizeof(t));
  114. }
  115. inline int lowbit(int x){
  116. return x&(-x);
  117. }
  118. void update(int p,int v){
  119. while(p<=n){
  120. t[p]^=v;
  121. p+=lowbit(p);
  122. }
  123. }
  124. int query(int p){
  125. int ret=0;
  126. while(p){
  127. ret^=t[p];
  128. p-=lowbit(p);
  129. }
  130. return ret;
  131. }
  132. }
  133. void getdiff(){
  134. for(int i=n;i>1;i--){
  135. a[i]^=a[i-1];
  136. }
  137. }
  138. signed main(){
  139. ios::sync_with_stdio(false);
  140. cin.tie(nullptr);
  141. cout.tie(nullptr);
  142. cin>>n>>m;
  143. for(int i=1;i<=n;i++){
  144. cin>>a[i];
  145. }
  146. BIT::clear();
  147. getdiff();
  148. for(int i=1;i<=n;i++){
  149. BIT::update(i,a[i]);
  150. }
  151. sgt::build(1,1,n);
  152. while(m--){
  153. int op,l,r,v;
  154. cin>>op>>l>>r>>v;
  155. if(op==1){
  156. BIT::update(l,v);
  157. sgt::update(l,v,1,1,n);
  158. if((r+1)<=n){
  159. BIT::update(r+1,v);
  160. sgt::update(r+1,v,1,1,n);
  161. }
  162. }
  163. else{
  164. int lft=BIT::query(l);
  165. if(l==r){
  166. // If l equals r
  167. // Then there are only two possibilities:LFT xor v | v
  168. cout<<max(v,lft^v)<<'\n';
  169. continue;
  170. }
  171. Basis::Basis result=sgt::query(l+1,r,1,1,n);
  172. result.insert(lft);
  173. cout<<(result.max_xor(v))<<'\n';
  174. }
  175. }
  176. return 0;
  177. }

题解 P5607 [Ynoi2013] 无力回天 NOI2017的更多相关文章

  1. 洛谷 P5607 [Ynoi2013] 无力回天 NOI2017

    人生第一道Ynoi,开心 Description https://www.luogu.com.cn/problem/P5607 Solution 拿到这个题,看了一下,发现询问要求最大异或和,怎么办? ...

  2. P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P5607 题目大意 \(n\)个数字的序列,\(m\)次操作 区间\([l,r]\)异或上一个值\(v\) 询问区间 ...

  3. 线段树套线性基——题解P4839 P哥的桶

    文章历史 2022-08-03: 文章初稿,由于对算法介绍过于少而被管理员打回重造. 2020-08-06:将算法介绍进行扩写,并删除了一些可有可无的内容或玩梗内容. 管理员审核题解辛苦了. 简要题意 ...

  4. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  5. [UOJ317]【NOI2017】游戏 题解

    题意 ​ 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. ​ 小 L 的赛车有三辆,分别用大写字母 A.B.C 表示.地图一共有四种,分别用小写字 ...

  6. BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...

  7. noi2017 day1 题解

    d1t1 sol1:用线段树维护区间是否全0/全1,叶子上压位维护对应位置的数位,加法首先对叶子加,如需进位则向右找到第一个不是全1的叶子+1,中间部分全1部分打上反转标记,减法同理. #includ ...

  8. BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...

  9. BZOJ4942 & UOJ314:[NOI2017]整数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4942 http://uoj.ac/problem/314 https://www.luogu.or ...

随机推荐

  1. 齐博x1头部底部菜单高亮设置

    下面这段是默认模板头部的导航菜单: {php}$menu_choose=config('system_dirname')?config('system_dirname'):'index';{/php} ...

  2. Sql Server 数据库分页存储过程书写

    create proc 存储过程名称( @page int, //pageindex @rows int, //pagesize @rowCount int out)as begin--定义字符串变量 ...

  3. RegExp正则表达式的匹配

    JavaScript RegExp 对象 RegExp 对象 正则表达式是描述字符模式的对象. 正则表达式用于对字符串模式匹配及检索替换,是对字符串执行模式匹配的强大工具. 语法 var patt=n ...

  4. ROS2时间同步(python)

    最近1周一直研究ROS2的时间同步,翻越很多博客,很少有人使用ROS2进行时间同步的代码,无奈不断尝试与源码阅读,终于将其搞定, 为此,本博客将介绍基于python的ROS2的时间同步方法. 本博客内 ...

  5. 二、.Net Core搭建Ocelot

    上一篇文章介绍了Ocelot的基本概念:https://www.cnblogs.com/yangleiyu/p/15043762.html 本文介绍在.net core中如何使用ocelot. Oce ...

  6. 搜索"xxxx"的进程,同时杀进程

    一.搜索"xxxx"的进程,同时杀进程,命令如下: ps -ef|grep xxxx|grep -v 'grep'|awk '{print $2}'|xargs kill -9 命 ...

  7. Websocket集群解决方案

    最近在项目中在做一个消息推送的功能,比如客户下单之后通知给给对应的客户发送系统通知,这种消息推送需要使用到全双工的websocket推送消息. 所谓的全双工表示客户端和服务端都能向对方发送消息.不使用 ...

  8. 数电第11周周结_by_yc

    Lab7_时序逻辑验证 一.简易电子时钟 功能描述:   设计一简易电子时钟,支持时.分.秒显示,其中HEX7-HEX6显示时,HEX5-HEX4显示分,HEX1-HEX0显示秒,假设进制为:18秒= ...

  9. PostgreSQL函数:查询包含时间分区字段的表,并更新dt分区为最新分区

    一.需求 1.背景 提出新需求后,需要在www环境下进行验收.故需要将www环境脚本每天正常调度 但由于客户库无法连接,ods数据无法每日取,且连不上客户库任务直接报错,不会跑ods之后的任务 故需要 ...

  10. windows安装grunt时提示不是内部或外部命令解决方案

    参考:https://www.cnblogs.com/hts-technology/p/8477258.html 安装windows安装elasticsearch-head时 不需要输入grunt s ...