题目描述

小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏。

每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且
让小葱从自己手中的小葱苗里选出一些小葱苗使得选出的小葱苗上的数字的异或和最大。
这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为Oi选手的你,你能帮帮他吗?
你只需要输出最大的异或和即可,若小葱手中没有小葱苗则输出0。

输入

第一行一个正整数n表示总时间;第二行n个整数a1,a2...an,若ai大于0代表给了小葱一颗数字为ai的小葱苗,否则代表从小葱手中拿走一颗数字为-ai的小葱苗。

输出

输出共n行,每行一个整数代表第i个时刻的最大异或和。

样例输入

6
1 2 3 4 -2 -3

样例输出

1
3
3
7
7
5


题解

线段树+高斯消元动态维护线性基

由于线性基不支持删除操作,所以我们需要离线来处理。

我们注意到每个数出现的时间都是一段连续的区间,所以可以使用map维护每个数的开始时间和结束时间,并在这一段区间上插入这个数。

我们肯定不能暴力在每个时间点上插入,所以需要线段树来降低时间复杂度。

在线段树的每个节点上开一个vector,存储这个区间的线性基。对于每个操作,在对应的vector上使用高斯消元动态维护线性基。

查询时,可以遍历整棵线段树,对于叶子结点直接使用贪心的方法查询并输出。但是如果将父亲节点的线性基暴力插入到儿子节点的话会导致MLE,于是需要记录一个新的节点,每次相当于将该节点的线性基插入到这个新的节点中。具体见代码。

时间复杂度$O(n\log^2n)$

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <map>
  5. #define N 500010
  6. using namespace std;
  7. struct data
  8. {
  9. vector<int> v;
  10. void insert(int x)
  11. {
  12. int i;
  13. for(i = 0 ; i < v.size() ; i ++ )
  14. if((x ^ v[i]) < x)
  15. x ^= v[i];
  16. if(x)
  17. {
  18. v.push_back(x);
  19. for(i = v.size() - 1 ; i ; i -- )
  20. {
  21. if(v[i] > v[i - 1]) swap(v[i] , v[i - 1]);
  22. else break;
  23. }
  24. }
  25. }
  26. int calc()
  27. {
  28. int i , ans = 0;
  29. for(i = 0 ; i < v.size() ; i ++ )
  30. if((ans ^ v[i]) > ans)
  31. ans ^= v[i];
  32. return ans;
  33. }
  34. }S[N << 2] , emp;
  35. map<int , int> f;
  36. int a[N];
  37. void update(int b , int e , int a , int l , int r , int x)
  38. {
  39. if(b <= l && r <= e)
  40. {
  41. S[x].insert(a);
  42. return;
  43. }
  44. int mid = (l + r) >> 1;
  45. if(b <= mid) update(b , e , a , l , mid , x << 1);
  46. if(e > mid) update(b , e , a , mid + 1 , r , x << 1 | 1);
  47. }
  48. void query(int l , int r , int x , data t)
  49. {
  50. int i , mid = (l + r) >> 1;
  51. for(i = 0 ; i < S[x].v.size() ; i ++ ) t.insert(S[x].v[i]);
  52. if(l == r)
  53. {
  54. printf("%d\n" , t.calc());
  55. return;
  56. }
  57. query(l , mid , x << 1 , t) , query(mid + 1 , r , x << 1 | 1 , t);
  58. }
  59. int main()
  60. {
  61. int n , i , x;
  62. scanf("%d" , &n);
  63. for(i = 1 ; i <= n ; i ++ )
  64. {
  65. scanf("%d" , &a[i]);
  66. if(a[i] > 0) f[a[i]] = i;
  67. else update(f[-a[i]] , i - 1 , -a[i] , 1 , n , 1) , f[-a[i]] = 0;
  68. }
  69. for(i = 1 ; i <= n ; i ++ )
  70. if(a[i] > 0 && f[a[i]])
  71. update(f[a[i]] , n , a[i] , 1 , n , 1);
  72. query(1 , n , 1 , emp);
  73. return 0;
  74. }

【bzoj4184】shallot 线段树+高斯消元动态维护线性基的更多相关文章

  1. 【bzoj4568】[Scoi2016]幸运数字 树上倍增+高斯消元动态维护线性基

    题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游 ...

  2. HDU3949:XOR(高斯消元)(线性基)

    传送门 题意 给出n个数,任意个数任意数异或构成一个集合,询问第k大个数 分析 这题需要用到线性基,下面是一些资料 1.高斯消元&线性基&Matirx_Tree定理 笔记 2.关于线性 ...

  3. bzoj2115 [Wc2011] Xor——高斯消元 & 异或线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法, ...

  4. BZOJ 4184 线段树+高斯消元

    思路: 线段树表示的是时间 每回最多log个段 区间覆盖 一直到叶子 的线性基 xor 一下 就是答案 一开始没有思路 看了这篇题解 豁然开朗 http://www.cnblogs.com/joyou ...

  5. BZOJ 4004: [JLOI2015]装备购买 [高斯消元同余 线性基]

    和前两(一)题一样,不过不是异或方程组了..... 然后bzoj的新数据是用来卡精度的吧..... 所有只好在模意义下做啦 只是巨慢无比 #include <iostream> #incl ...

  6. 【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基

    题目描述 输入 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图 ...

  7. 【BZOJ-2460&3105】元素&新Nim游戏 动态维护线性基 + 贪心

    3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 839  Solved: 490[Submit][Stat ...

  8. BZOJ 2466: [中山市选2009]树( 高斯消元 )

    高斯消元解异或方程组...然后对自由元进行暴搜.树形dp应该也是可以的... ------------------------------------------------------------- ...

  9. 【BZOJ】2466: [中山市选2009]树 高斯消元解异或方程组

    [题意]给定一棵树的灯,按一次x改变与x距离<=1的点的状态,求全0到全1的最少次数.n<=100. [算法]高斯消元解异或方程组 [题解]设f[i]=0/1表示是否按第i个点的按钮,根据 ...

随机推荐

  1. java面试题(杨晓峰)---第二讲Exception和Error有什么区别?

    本人总结: Exception和Error:正常问题和意外问题,以自行车举例:没气和爆胎. ①理解Throwable,Exception,Error的设计和分类. ②掌握哪些应用最广泛的子类, ③如何 ...

  2. UVA 11732 strcmp() Anyone (Trie+链表)

    先两两比较,比较次数是两者相同的最长前缀长度*2+1,比较特殊的情况是两者完全相同时候比较次数是单词长度*2+2, 两个单词'末尾\0'和'\0'比较一次,s尾部'\0'和循环内'\0'比较一次. 因 ...

  3. netbackup如何手动获取主机ID证书。

    如何手动获取主机ID证书.   文章:100039650 最后发布:2017-09-21 评分:  20 11 产品:NetBackup 问题 从NetBackup V8.1开始,管理员需要在证书颁发 ...

  4. hd - MFM/IDE 硬盘设备

    描述 DESCRIPTION hd* 开头的设备是以裸模式(raw mode)访问MFM/IDE类型硬盘的块设备. 第一个IDE驱动控制器上的主盘(主设备号3)是 hda ;从盘是 hdb. 第二个I ...

  5. 谷歌浏览器 加安全地址 快捷方式加参数 chrome

    --unsafely-treat-insecure-origin-as-secure="http://192.168.43.17:8080"

  6. 【Python学习之五】高级特性5(切片、迭代、列表生成器、生成器、迭代器)

    5.迭代器 由之前的生成器可知,for循环用于可迭代对象:Iterable.包括集合数据类型: list.tuple.dict.set.str 等,以及两种生成器.判断迭代器,使用 isinstanc ...

  7. 06grep与find命令详解

    1. grep 命令 grep 命令用于在文本中执行关键词搜索,并显示匹配的结果,格式为"grep [选项][文件]". grep 命令的参数及其作用如下: -b 将可执行文件(b ...

  8. thinkcmf5更新模板代码分析,解决模板配置json出错导致数据库保存的配置项内容丢失问题

    private function updateThemeFiles($theme, $suffix = 'html') { $dir = 'themes/' . $theme; $themeDir = ...

  9. OC8051项目启动

  10. 22.Yii2.0框架多表关联一对一查询之hasOne

    思路: 通过文章查它对应的分类信息 一对一的关系 控制器里 //一对一关联查询 public function actionRelatesone() { //方法一,hasOne() 用查一条文章的结 ...