题目描述

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

每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且
让小葱从自己手中的小葱苗里选出一些小葱苗使得选出的小葱苗上的数字的异或和最大。
这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为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)$

#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#define N 500010
using namespace std;
struct data
{
vector<int> v;
void insert(int x)
{
int i;
for(i = 0 ; i < v.size() ; i ++ )
if((x ^ v[i]) < x)
x ^= v[i];
if(x)
{
v.push_back(x);
for(i = v.size() - 1 ; i ; i -- )
{
if(v[i] > v[i - 1]) swap(v[i] , v[i - 1]);
else break;
}
}
}
int calc()
{
int i , ans = 0;
for(i = 0 ; i < v.size() ; i ++ )
if((ans ^ v[i]) > ans)
ans ^= v[i];
return ans;
}
}S[N << 2] , emp;
map<int , int> f;
int a[N];
void update(int b , int e , int a , int l , int r , int x)
{
if(b <= l && r <= e)
{
S[x].insert(a);
return;
}
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , a , l , mid , x << 1);
if(e > mid) update(b , e , a , mid + 1 , r , x << 1 | 1);
}
void query(int l , int r , int x , data t)
{
int i , mid = (l + r) >> 1;
for(i = 0 ; i < S[x].v.size() ; i ++ ) t.insert(S[x].v[i]);
if(l == r)
{
printf("%d\n" , t.calc());
return;
}
query(l , mid , x << 1 , t) , query(mid + 1 , r , x << 1 | 1 , t);
}
int main()
{
int n , i , x;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d" , &a[i]);
if(a[i] > 0) f[a[i]] = i;
else update(f[-a[i]] , i - 1 , -a[i] , 1 , n , 1) , f[-a[i]] = 0;
}
for(i = 1 ; i <= n ; i ++ )
if(a[i] > 0 && f[a[i]])
update(f[a[i]] , n , a[i] , 1 , n , 1);
query(1 , n , 1 , emp);
return 0;
}

【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 文件操作-RandomAccessFile

    1. RandomAccessFile     Java提供了一个可以对文件随机访问的操作,访问包括读和写操作.该类名为RandomAccessFile.该类的读写是基于指针的操作. 1)文件访问模式 ...

  2. UVA 11988 Broken Keyboard (链表)

    简单题,题目要求显然是很多次插入,所以是链表. 插入两个语句,nxt[i] = nxt[u] 表示 i结点指向u的后继, nxt[u] = i表示把u的后继设成i. 设置一个头结点,指向一个不存在的结 ...

  3. 使用Timer组件实现人物动画效果

    实现效果: 知识运用: Graphics类的DrawImage方法 //在指定位置 按原始大小绘制指定的Image对象 public void DrawImage(Image image,Point ...

  4. Java中的后台线程和join方法

    /*守护线程(后台线程):在一个进程中如果只剩下 了守护线程,那么守护线程也会死亡. 需求: 模拟QQ下载更新包. 一个线程默认都不是守护线程. */ public class Demo extend ...

  5. 从 Objective-C 里的 Alloc 和 AllocWithZone 谈起

    一.问题起源 一切起源于Apple官方文档里面关于单例(Singleton)的示范代码:Creating a Singleton Instance.主要的争议集中在下面这一段: static MyGi ...

  6. Android读书笔记四

    第四章 这是一次源代码之旅,学到了如何下载和编译Android源代码和Linux内核源代码.来详细阐述一下一些具体过程 一.Android源代码下载环境 1.安装下载Android源代码的环境配置 ( ...

  7. BZOJ 2002 弹飞绵羊(分块)

    题目:弹飞绵羊 这道题,据说是lct裸题,但是lct那么高级的数据结构,我并不会,所以采取了学长讲过的分块做法,我们对序列分块,可以定义两个数组,其中一个表示从当前位置跳出当前块需要多少步,另一个数组 ...

  8. 【Redis】DENIED Redis is running in protected mode

    .修改redis服务器的配置文件 vi redis.conf 注释以下绑定的主机地址 # bind 127.0.0.1 .修改redis服务器的参数配置 修改redis的守护进程为no ,不启用 &g ...

  9. java中类与对象的概念(2013-05-04-bd 写的日志迁移

    1:类是抽象的,概念的,代表一类事物,比如人类.猫类.. 2:对象是具体的,实际的,代表一个具体的事物 3:类是对象的模板,对象是类的一个个体,实例 创建对象的两种方法: 1.先声明在创建 对象声明: ...

  10. Linux系统入门-Bash初识

    目录 Linux系统入门-Bash初识 Bash Shell介绍 Bash Shell的作用 Bash的两种使用方式 命令提示符 shell的基础语法 shell的基本特性 命令补全 linux快捷键 ...