题目


分析

考虑区间修改比较难操作,将数组差分一下,转化成两次单点修改。

这样查询前缀的异或值就是该位置的异或值,线性基可以用线段树维护,

那么取出 \((l,r]\) 所在的线性基,再将 \(a[l]\) 扔入线性基查询最大异或值即可

因为如果要取出 \(a_x\) 实则就是取出 \(a_l\) xor \(b_{l+1}\) xor \(\dots\) xor \(b_x\)。

所以区间异或有时转化成差分加单点异或,维护区间线性基可以这样做。


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
const int N=50011;
int a[N],n,m;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Vector_Space{
int re[30],now;
inline void BUILD(){memset(re,0,sizeof(re));}
inline void Insert(int x){
for (rr int i=29;~i;--i)
if ((x>>i)&1){
if (re[i]) x^=re[i];
else {re[i]=x; return;}
}
}
inline signed query(int x){
for (rr int i=29;~i;--i)
if ((x^re[i])>x) x^=re[i];
return x;
}
}w[N<<2];
inline Vector_Space Merge(Vector_Space A,Vector_Space B){
for (rr int i=29;~i;--i)
if (B.re[i]) A.Insert(B.re[i]);
A.now^=B.now;
return A;
}
inline void build(int k,int l,int r){
if (l==r) {w[k].Insert(w[k].now^=a[l]); return;}
rr int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
w[k]=Merge(w[k<<1],w[k<<1|1]);
}
inline void update(int k,int l,int r,int x,int y){
if (l==r) {w[k].BUILD(),w[k].Insert(w[k].now^=y); return;}
rr int mid=(l+r)>>1;
if (x<=mid) update(k<<1,l,mid,x,y);
else update(k<<1|1,mid+1,r,x,y);
w[k]=Merge(w[k<<1],w[k<<1|1]);
}
inline signed query(int k,int l,int r,int x){
if (l==r) return w[k].now;
rr int mid=(l+r)>>1;
if (x<=mid) return query(k<<1,l,mid,x);
else return query(k<<1|1,mid+1,r,x)^w[k<<1].now;//前缀xor
}
inline Vector_Space Query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
rr int mid=(l+r)>>1;
if (y<=mid) return Query(k<<1,l,mid,x,y);
else if (x>mid) return Query(k<<1|1,mid+1,r,x,y);
else return Merge(Query(k<<1,l,mid,x,mid),Query(k<<1|1,mid+1,r,mid+1,y));
}
signed main(){
n=iut(); m=iut();
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=n;i>1;--i) a[i]^=a[i-1];
build(1,1,n);
for (rr int i=1;i<=m;++i){
rr int opt=iut(),l=iut(),r=iut(),x=iut();
if (opt==1){
update(1,1,n,l,x);
if (r<n) update(1,1,n,r+1,x);
}else{
rr int Al=query(1,1,n,l);
if (l==r) {print(x>(x^Al)?x:(x^Al)),putchar(10); continue;}
rr Vector_Space t=Query(1,1,n,l+1,r);
t.Insert(Al),print(t.query(x)),putchar(10);
}
}
return 0;
}

#线性基,差分,线段树#洛谷 5607 [Ynoi2013] 无力回天 NOI2017的更多相关文章

  1. CodeForces - 587E[线段树+线性基+差分] ->(线段树维护区间合并线性基)

    题意:给你一个数组,有两种操作,一种区间xor一个值,一个是查询区间xor的结果的种类数 做法一:对于一个给定的区间,我们可以通过求解线性基的方式求出结果的种类数,而现在只不过将其放在线树上维护区间线 ...

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

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

  3. 【Luogu3733】[HAOI2017]八纵八横(线性基,线段树分治)

    [Luogu3733][HAOI2017]八纵八横(线性基,线段树分治) 题面 洛谷 题解 看到求异或最大值显然就是线性基了,所以只需要把所有环给找出来丢进线性基里就行了. 然后线性基不资磁撤销?线段 ...

  4. bzoj 4184: shallot【线性基+时间线段树】

    学到了线段树新姿势! 先离线读入,根据时间建一棵线段树,每个节点上开一个vector存这个区间内存在的数(使用map来记录每个数出现的一段时间),然后在线段树上dfs,到叶子节点就计算答案. 注意!! ...

  5. 线段树 洛谷P3932 浮游大陆的68号岛

    P3932 浮游大陆的68号岛 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无 ...

  6. [线段树]洛谷P5278 算术天才⑨与等差数列

    题目描述 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k ...

  7. 区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel

    https://www.luogu.org/problem/P2894 #include<cstdio> #include<iostream> using namespace ...

  8. 【bzoj5028】小Z的加油店 扩展裴蜀定理+差分+线段树

    题目描述 给出 $n$ 个瓶子和无限的水,每个瓶子有一定的容量.每次你可以将一个瓶子装满水,或将A瓶子内的水倒入B瓶子中直到A倒空或B倒满.$m$ 次操作,每次给 $[l,r]$ 内的瓶子容量增加 $ ...

  9. [Luogu5327][ZJOI2019]语言(树上差分+线段树合并)

    首先可以想到对每个点统计出所有经过它的链的并所包含的点数,然后可以直接得到答案.根据实现不同有下面几种方法.三个log:假如对每个点都存下经过它的链并S[x],那么每新加一条路径进来的时候,相当于在路 ...

  10. [BZOJ3307] 雨天的尾巴(树上差分+线段树合并)

    [BZOJ3307] 雨天的尾巴(树上差分+线段树合并) 题面 给出一棵N个点的树,M次操作在链上加上某一种类别的物品,完成所有操作后,要求询问每个点上最多物品的类型. N, M≤100000 分析 ...

随机推荐

  1. Xray安全评估工具使用

    xray 是一款功能强大的安全评估工具,主要特性有: 检测速度快.发包速度快; 漏洞检测算法高效. 支持范围广.大至 OWASP Top 10 通用漏洞检测,小至各种 CMS 框架 POC,均可以支持 ...

  2. 【LeetCode贪心#02】摆动序列,麻了

    摆动序列 力扣题目链接(opens new window) 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动 ...

  3. 【转载】重装系统小贴士:ssh、vscode免密登录

    ssh安装 apt install openssh-server 然后到cd /etc/ssh下找sshd_config文件,打开把允许远程root登录的选项改为yes 重启ssh服务:/etc/in ...

  4. logback中使用MDC自定义日志输出格式

    logback-MDC 相当于自定义日志格式输出 写在过滤器中 示例: try { Context context = createContext(request, response); proces ...

  5. 【Azure 媒体服务】在Azure Media Service门户中使用HLS模式传输视频流,播放视频步骤

    问题描述 如何在Azure Media Service门户中使用HLS模式传输视频流,播放视频步骤 问题解决 第一步:在 Media Service 这边点击资产.上传本地视频资源作为Media Se ...

  6. 【工具】用nvm管理nodejs版本切换,真香!

    前言 缘由 换个nodejs版本比换个媳妇还难,nvm堪称管理nodejs版本神器 事情的起因,公司的一些老项目需要依赖稳定老版本的nodejs,但是自己的一些项目所需要的是更高版本的nodejs,这 ...

  7. Java 封装性的四种权限测试 + 总结

    *    总结封装性:Java提供了4中权限修饰符来修饰类及类的内部结构,体现类及类的内部结构再被调用时的可见性的大小 1 package com.bytezero.circle; 2 3 publi ...

  8. Java开发者的Python快速进修指南:掌握T检验

    前言 T检验是一种用于比较两个独立样本均值差异的统计方法.它通过计算T值和P值来判断样本之间是否存在显著性差异.通常情况下,我们会有两组数据,例如一组实验组和一组对照组. T检验的原假设是两组样本的均 ...

  9. RIPEMD算法:多功能哈希算法的瑰宝

    一.RIPEMD算法的起源与历程 RIPEMD(RACE Integrity Primitives Evaluation Message Digest)算法是由欧洲研究项目RACE发起,由Hans D ...

  10. Java面试必考题之线程的生命周期,结合源码,透彻讲解!

    写在开头 在前面的几篇博客里,我们学习了Java的多线程,包括线程的作用.创建方式.重要性等,那么今天我们就要正式踏入线程,去学习更加深层次的知识点了. 第一个需要学的就是线程的生命周期,也可以将之理 ...