P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】
正题
题目链接:https://www.luogu.com.cn/problem/P5607
题目大意
\(n\)个数字的序列,\(m\)次操作
- 区间\([l,r]\)异或上一个值\(v\)
- 询问区间\([l,r]\)中选出一些数来异或的最大异或和
解题思路
最大异或和的话只能是线性基了,但是线性基的区间修改又不能通过打标记的方法。
不能区间修改就转单点修改,我们定义一个序列\(b_i=a_i\ xor\ a_{i-1}\)。这样修改的时候就可以单点进行修改了。
但是这样好像会影响我们的查询操作,考虑查询区间\([l,r]\)的时候,我们会选出若干个前缀来进行操作,被异或多次的区间会抵消掉一些,如果选择了\(b_x\)就可以理解为选择了\(a_{x-1}\ xor\ a_{x}\)。
但是会发现\(b_{1\sim l}\)也就是\(a_l\)可能会被异或很多次,其实可以把\(b_{l+1\sim r}\cup a_l\)的线性基拿出来跑就是答案了。因为如果在\([l+1,r]\)这个范围无论选择了奇偶个都可以用\(a_l\)来决定前面区间的异或次数。
\(a_l\)的话我们再维护一个树状数组来查询就好了,注意一下细节就行了
时间复杂度\(O((n+m)\log n\log^2 w)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
using namespace std;
const int N=5e4+10;
struct xxj{
int d[32];
void init(){memset(d,0,sizeof(d));}
void Insert(int x){
for(int i=30;i>=0;i--)
if((x>>i)&1){
if(d[i])x^=d[i];
else{
d[i]=x;
return;
}
}
return;
}
int Query(int x){
for(int i=30;i>=0;i--)
if((x^d[i])>x)x^=d[i];
return x;
}
}c,w[N<<2],ans;
int n,m,a[N],t[N];
void Add(xxj &a,xxj &b){
for(int i=0;i<=30;i++)
if(b.d[i])a.Insert(b.d[i]);
return;
}
void Change(int x,int L,int R,int pos,int val){
if(L==R){w[x].init();a[L]^=val;w[x].Insert(a[L]);return;}
int mid=(L+R)>>1;
if(pos<=mid)Change(x*2,L,mid,pos,val);
else Change(x*2+1,mid+1,R,pos,val);
w[x]=w[x*2];Add(w[x],w[x*2+1]);
return;
}
void Ask(int x,int L,int R,int l,int r){
if(L==l&&R==r){Add(ans,w[x]);return;}
int mid=(L+R)>>1;
if(r<=mid)Ask(x*2,L,mid,l,r);
else if(l>mid)Ask(x*2+1,mid+1,R,l,r);
else Ask(x*2,L,mid,l,mid),Ask(x*2+1,mid+1,R,mid+1,r);
return;
}
void Change(int x,int val){
while(x<=n){
t[x]^=val;
x+=lowbit(x);
}
return;
}
int Ask(int x){
int ans=0;
while(x){
ans^=t[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=n;i>=1;i--){
int p=a[i]^a[i-1];a[i]=0;
Change(1,1,n,i,p);Change(i,p);
}
while(m--){
int op,l,r,x;
scanf("%d%d%d%d",&op,&l,&r,&x);
if(op==1){
Change(l,x);Change(r+1,x);
Change(1,1,n,l,x);
if(r<n)Change(1,1,n,r+1,x);
}
else{
ans.init();
if(l<r)Ask(1,1,n,l+1,r);
int mx=ans.Query(x);
mx=max(mx,ans.Query(x^Ask(l)));
printf("%d\n",mx);
}
}
return 0;
}
P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】的更多相关文章
- 洛谷 P5607 [Ynoi2013] 无力回天 NOI2017
人生第一道Ynoi,开心 Description https://www.luogu.com.cn/problem/P5607 Solution 拿到这个题,看了一下,发现询问要求最大异或和,怎么办? ...
- loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)
题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...
- 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)
LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...
- ACM-ICPC 2017 Asia Xi'an A XOR (线性基+线段树思想)
题目链接 题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值 题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后用线段树维护线性 ...
- ACM-ICPC 2017 西安赛区现场赛 A. XOR(线性基+线段树)
题目链接:https://nanti.jisuanke.com/t/20749 参考题解:https://blog.csdn.net/Lee_w_j__/article/details/8266418 ...
- CodeForces - 1100F:Ivan and Burgers (线性基&贪心)(离线 在线)
题意:给定N个数,Q次询问,求区间最大异或和. 思路:一开始想的线性基+线段树.单次线性基合并的复杂度为20*20,结合线段树,复杂度为O(NlogN*20*20):显然,超时. 超时代码: #inc ...
- HDU - 3949 :XOR(线性基,所有集合的不同异或和中,求从小到大第K个)
XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A ...
- 前缀和线性基HDU6579
Operation 题解:看到区间最大异或和,首先想到的是线性基: 线性基可以处理的操作是: 在数列末尾插入一个数 查询全局的子集异或最大值 由于线性基的长度很短,因此我们可以将数列所有前缀的线性基保 ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
随机推荐
- python创建一个简单的服务
python -m http.server 8000 --bind 0.0.0.0 8000为端口 0.0.0.0允许远程访问
- 十九:JDBC操作事务
二.MySQL数据库中操作事务命令 2.1.开启事务(start transaction) 使用"start transaction"开启MySQL数据库的事务,如下所示:
- Failed to start LSB: Bring up/down错误解决方法
很多朋友在使用centos7系统时,有时候需要分配多个IP地址,这就涉及到修改网卡配置,但是在修改完网卡配置时,重启网络服务时会出现"Failed to start LSB: Bring u ...
- Map 综述(二):彻头彻尾理解 LinkedHashMap
摘要: HashMap和双向链表合二为一即是LinkedHashMap.所谓LinkedHashMap,其落脚点在HashMap,因此更准确地说,它是一个将所有Entry节点链入一个双向链表的Hash ...
- Go: LeetCode简单题,简单做(sort.Search)
前言 正值端午佳节,LeetCode也很懂.这两天都是简单题,早点做完去包粽子. 故事从一道简单题说起 第一个错误的版本 简单题 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最 ...
- list类型数据的操作指令
1. 结果是 3 2 1 还可以继续追加如下: 2. 3. 4.删除表头元素(最左侧的元素),并返回该元素 5. 6. 7.删除表尾的元素(最右侧的元素),并返回该元素 8.
- TCP可靠传输原理
停止等待协议 "停止等待"就是发送方在发送完一个分组后停止发送,等待接收方的确认后再继续发送. 超时重传 发送方在等待一定时间后如果还没有收到接收方的确认,此时发送方将认定分组没有 ...
- python3 spider [ urllib.request ]
# # 导入urllib库的urlopen函数 # from urllib.request import urlopen # # 发出请求,获取html # html = urlopen(" ...
- AOP快速入门
一.概念 AOP面向切面编程,是函数式编程的延申,是对OOP的补充: 代理模式:拦截增强作用,增强功能: 1.java继承,纵向共性抽取, 2.横向切面AOP织入增强代码方式 二.原理是通过代理机制, ...
- python模块--glob, fnmatch
包/方法 返回值 参数 说明 glob Unix shell样式的路径扩展 .glob() list 匹配满足规则的所有路径(默认以 . 开头的文件不会匹配到, 可以用 .* 来匹配) pat ...