前缀和线性基HDU6579
Operation

题解:看到区间最大异或和,首先想到的是线性基;
线性基可以处理的操作是:
- 在数列末尾插入一个数
- 查询全局的子集异或最大值
由于线性基的长度很短,因此我们可以将数列所有前缀的线性基保存下来。1到x的线性基可以由1到x-1的线性基通过插入a[x]来求得,这样,我们就可以查询前缀区间的子集异或最大值。现在问题的关键在于,查询区间 [L, R] 时,如何避免 [1, L-1] 的干扰。
考虑线性基的插入过程,如果线性基当前位上已经有值,我们就不能把待插入的值放入这一位,因此线性基上每一位的数,都是对应位上在原数列最左侧的数字。现在我们改变策略,使得线性基上每一位的数,都变成对应位上在原数列最右侧的数字。实现这个策略的方法是:我们额外保存线性基上每一位数在原数列中的位置,插入的时候,如果对应位上的数在原数列中更靠左,就用待插入的数和它交换。基于这种策略,我们在查询区间 [L, R] 时,可以在区间 [1, R] 对应的线性基中查询,对于线性基上每一位的数,如果它在原数组中出现的位置比 L 更靠右,就考虑它对答案的贡献,否则直接跳过这一位。
这个做法的正确性也很显然,通过改变策略,使线性基上每一位数变成对应位上在原数列最右侧的数字,可以看成线性基插入数字的顺序变反,完全不影响线性基的性质。同时,将线性基上所有在原数组中的位置比 x 更靠左的数字删除,可以视为区间 [1, L-1] 的数字还没有被插入线性基。
复杂度:O((n + m) logx),n为初始数列长度,m为操作次数,x为值域大小。
大佬的博客讲解:here
AC_Code:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
#define endl '\n'
const int maxn = ;
const int maxm = 5e5+;
const int inf = 0x3f3f3f3f; int cnt;//当前已插入的数的个数
int a[maxm][maxn];//保存所有前缀区间的线性基
int b[maxm][maxn];//保存线性基上的数字在原数组上的对应位置
int n,m; void LB(int x){
int cur=++cnt;//表示待插入的数字在原数组上的位置
for(int i=;i>=;i--){
a[cnt][i]=a[cnt-][i];
b[cnt][i]=b[cnt-][i];
}
for(int i=;i>=;i--){
if( !(x>>i) ) continue;
if( !a[cnt][i] ){
a[cnt][i]=x;
b[cnt][i]=cur;
break;
}
else{
if( cur>b[cnt][i] ){ //如果待插入的数字在原数组上更靠右,则用线性基上的数与其交换
swap(a[cnt][i],x);
swap(b[cnt][i],cur); //位置也要交换
}
x^=a[cnt][i];
}
}
} int query(int l,int r){
l=l%cnt+; r=r%cnt+; //注意这里是%cnt,不是%n
if( l>r ) swap(l,r);
int ret=;
for(int i=;i>=;i--){
if( b[r][i]>=l ){ //如果在原数组中的位置比l更靠右,那么就产生贡献,此处b[r][i]就已经限制了右区间
ret=max(ret,ret^a[r][i]); //线性基贪心求最大值的基本操作
}
}
return ret;
} int main()
{
int t; scanf("%d",&t);
while( t-- ){
cnt=;
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
int a;
scanf("%d",&a);
LB(a);
}
int lastans=, opt, x, y; //lastans用于处理强制在线
for(int i=;i<m;i++){
scanf("%d%d",&opt,&x);
if( opt== ){
scanf("%d",&y);
x=x^lastans;
y=y^lastans;
lastans = query(x, y);
printf("%d\n",lastans);
}
else{
LB(x^lastans);
}
}
}
return ;
}
前缀和线性基HDU6579的更多相关文章
- CodeForces - 1100F:Ivan and Burgers (线性基&贪心)(离线 在线)
题意:给定N个数,Q次询问,求区间最大异或和. 思路:一开始想的线性基+线段树.单次线性基合并的复杂度为20*20,结合线段树,复杂度为O(NlogN*20*20):显然,超时. 超时代码: #inc ...
- HDU6579 2019HDU多校训练赛第一场1002 (线性基)
HDU6579 2019HDU多校训练赛第一场1002 (线性基) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6579 题意: 两种操作 1.在序列末 ...
- codeforces 1101G (Zero XOR Subset)-less 前缀异或+线性基
题目传送门 题意:给出一个序列,试将其划分为尽可能多的非空子段,满足每一个元素出现且仅出现在其中一个子段中,且在这些子段中任取若干子段,它们包含的所有数的异或和不能为0. 思路:先处理出前缀异或,这样 ...
- [2019杭电多校第一场][hdu6579]Operation(线性基)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6579 题目大意是两个操作,1个是求[l,r]区间子序列的最大异或和,另一个是在最后面添加一个数. 如果 ...
- 2019杭电多校第一场hdu6579 Operation(线性基)
Operation 题目传送门 解题思路 把右边的数尽量往高位放,构造线性基的时候同时记录其在原序列中的位置,在可以插入的时候如果那个位置上存在的数字的位置比新放入的要小,就把旧的往后挤.用这种发现构 ...
- Codeforces1101G (Zero XOR Subset)-less 【线性基】【贪心】
题目分析: 考虑到这是一个区间的异或问题,不妨求出前缀和,令$sum[i] = Xor_{j=1}^{i}a[j]$. 对于区间$[l,r]$的异或结果,等于$sum[r] \oplus sum[l- ...
- CF1101G (Zero XOR Subset)-less 线性基
传送门 既然每一次选择出来的都是一个子段,不难想到前缀和计算(然而我没有想到--) 设异或前缀和为\(x_i\),假设我们选出来的子段为\([1,i_1],(i_1,i_2],...,(i_{k-1} ...
- bzoj 2115 Xor - 线性基 - 贪心
题目传送门 这是个通往vjudge的虫洞 这是个通往bzoj的虫洞 题目大意 问点$1$到点$n$的最大异或路径. 因为重复走一条边后,它的贡献会被消去.所以这条路径中有贡献的边可以看成是一条$1$到 ...
- ACM线性基学习笔记
https://www.cnblogs.com/31415926535x/p/11260897.html 概述 最近的几场多校出现了好几次线性基的题目,,会想起之前在尝试西安区域赛的一道区间异或和最大 ...
随机推荐
- 四层发现-TCP发现
直接向目标ip发送一个ACK数据包,正常情况下up状态的目标ip会返回一个SRT数据包. 使用scapy构造TCP数据包: 然后在将一些数据类型设置好就可以发送了. 实用脚本实现批量扫描: #!/us ...
- java8 Optional 类
package jdk180reduce; import java.util.ArrayList; import java.util.HashMap; import java.util.List; i ...
- .net core 静态类获取appsettings
注入获取 通过IConfiguration直接获取的方法官方文档里就有,可以直接看这里 如:appsettings.json { "Position": { "Title ...
- css常用的简写技巧_css background简写、css border 简写、css font属性简写等
css样式中有很多简写方式,比如:设置背景,字体,边框,盒子等.我们都可以把css代码合并为一行,这篇文章将总结有哪些属性支持css简写. 1.背景background属性 background-co ...
- 虚拟机中Linux环境搭建
Linux系统搭建 作为一名软件测试资深工程师,在日常工作中离不开对测试环境的操作.我们测试的软件,系统都是部署在linux系统环境上,我们掌握Linux系统的日常操作是非常必要的.那么在学习Linu ...
- 一天学习一点之express demo
接着上一篇,安装了nodejs之后,再安装express,顺序执行以下命令 1.npm -g install express; 2.npm -g express-generator; 3.使用exp ...
- SpringBoot01-启动类启动做了那些事情
1.第一个步骤进入SpringApplication构造函数 public SpringApplication(ResourceLoader resourceLoader, Class<?> ...
- The Meaningless Game,算是思维吧。
题目直接链接 题意: 某游戏规则:每次选定数字k(正整数),两人初始分数为1,获胜者分数乘k2,失败者分数成k,给你两个数字,判断是否可能是本游戏的两人的得分. 分析: 为啥题意我不写判断两个数可不可 ...
- BUUCTF-Crypyo-No.1
我我我我我又来惹~~~~* MD5 flag{admin1} 看我回旋踢 凯撒密码 flag{5cd1004d-86a5-46d8-b720-beb5ba0417e1} Url编码 flag{and ...
- VS2017未能添加对"System.Drawing.dll"的引用
问题: 解决方法:在程序集中找到System.Drawing.dll然后勾选引用.