简要题意

其实我觉得这个部分可以不要,因为这道题的题面还是很清晰的。

你需要维护一个数据结构,支持区间异或和区间求与 \(v\) 的最大异或和。

思路

对于这种区间问题,最容易想到的就是 分块 线段树。

而对于复杂的异或问题,最容易想到的就是 01 Trie 线性基。

合在一起,就是线段是套线性基。(好像还用了顶针的手法)

做这道题之前建议先做 P4839 P哥的桶 那是这一道题的弱化版。

(现在默认大家已经做过P哥的桶了)

P哥的桶中,是单点修改,而这道题是区间修改,用传统的打tag是不方便维护的,我们可以用差分的思想。

Sol1大佬的文章已经有了正确性证明,我这里就口胡一下结论:

我们可以维护异或差分数组 \(b\),然后每次询问 \([l,r]\) 就在线段树上询问 \([l+1,r]\),再插入 \(a_l\) 即可。

然后就是一个差分的过程,随便找一个数据结构维护一下即可。(这里是树状数组)

细节

(由于没特判 \(l=r\) \(45\) 分挂了很久)

注意要特判 \(l=r\),如果 \(l=r\),那么就可以分类讨论一下,答案就是 \(\max\{\operatorname{BIT.query}(l) \operatorname{xor} v,v\}\)。

下面代码的注释也有说明(虽然是蹩脚的英文的)

代码

(纪念,这是我A的第二道Ynoi,也是第一篇试图提交题解的Ynoi)

里面有一份线性基模板,如果您觉得我的代码好,可以参考。

不用卡常,好耶!

#include <bits/stdc++.h>
#define int long long
using namespace std; namespace Basis{
const int MAX_BIT = 30;
struct Basis{
int p[MAX_BIT+5];
int _how_many_numbers_can_xor;
void clear(){
memset(p,0,sizeof(p));
_how_many_numbers_can_xor=0;
}
Basis(){
clear();
}
void insert(int x){
for(int i=MAX_BIT;i>=0;i--){
if(!(x&(1ll<<i)))continue;
if(!p[i]){
p[i]=x;
_how_many_numbers_can_xor++;
break;
}
x^=p[i];
}
}
int max_xor(int init=0){
int ans=init;
for(int i=MAX_BIT;i>=0;i--){
if((ans^p[i])>ans){
ans^=p[i];
}
}
return ans;
}
bool can_be_xor(int x){
for(int i=MAX_BIT;i>=0;i--){
if(x&(1ll<<i))x^=p[i];
}
return x==0;
}
int numbers_can_xor(){
return (1ll<<_how_many_numbers_can_xor);
}
void expand(Basis &x){
for(int i=MAX_BIT;i>=0;i--){
if(x.p[i]){
insert(x.p[i]);
}
}
}
}; Basis merge(Basis x,Basis y){
for(int i=MAX_BIT;i>=0;i--){
if(y.p[i])x.insert(y.p[i]);
}
return x;
}
} int n,m;
int a[50005]; namespace sgt{
Basis::Basis t[200005]; void pushup(int i){
t[i]=Basis::merge(t[i<<1],t[i<<1|1]);
}
void build(int i,int l,int r){
for(int ii=l;ii<=r;ii++){
t[i].insert(a[ii]);
}
if(l==r){
return;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
pushup(i);
}
void update(int x,int v,int i,int l,int r){
if(l==r){
t[i].clear();
a[l]^=v;
t[i].insert(a[l]);
return;
}
int mid=(l+r)>>1;
if(x<=mid){
update(x,v,i<<1,l,mid);
}
else{
update(x,v,i<<1|1,mid+1,r);
}
pushup(i);
}
Basis::Basis query(int ql,int qr,int i,int l,int r){
if(ql<=l&&r<=qr){
return t[i];
}
Basis::Basis result;
int mid=(l+r)>>1;
if(ql<=mid){
result=merge(result,query(ql,qr,i<<1,l,mid));
}
if(qr>mid){
result=merge(result,query(ql,qr,i<<1|1,mid+1,r));
}
return result;
}
} namespace BIT{
int t[50005];
void clear(){
memset(t,0,sizeof(t));
}
inline int lowbit(int x){
return x&(-x);
}
void update(int p,int v){
while(p<=n){
t[p]^=v;
p+=lowbit(p);
}
}
int query(int p){
int ret=0;
while(p){
ret^=t[p];
p-=lowbit(p);
}
return ret;
}
} void getdiff(){
for(int i=n;i>1;i--){
a[i]^=a[i-1];
}
} signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
BIT::clear();
getdiff();
for(int i=1;i<=n;i++){
BIT::update(i,a[i]);
}
sgt::build(1,1,n);
while(m--){
int op,l,r,v;
cin>>op>>l>>r>>v;
if(op==1){
BIT::update(l,v);
sgt::update(l,v,1,1,n);
if((r+1)<=n){
BIT::update(r+1,v);
sgt::update(r+1,v,1,1,n);
}
}
else{
int lft=BIT::query(l);
if(l==r){
// If l equals r
// Then there are only two possibilities:LFT xor v | v
cout<<max(v,lft^v)<<'\n';
continue;
}
Basis::Basis result=sgt::query(l+1,r,1,1,n);
result.insert(lft);
cout<<(result.max_xor(v))<<'\n';
}
}
return 0;
}

题解 P5607 [Ynoi2013] 无力回天 NOI2017的更多相关文章

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

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

  2. P5607-[Ynoi2013]无力回天NOI2017【线性基,线段树,树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P5607 题目大意 \(n\)个数字的序列,\(m\)次操作 区间\([l,r]\)异或上一个值\(v\) 询问区间 ...

  3. 线段树套线性基——题解P4839 P哥的桶

    文章历史 2022-08-03: 文章初稿,由于对算法介绍过于少而被管理员打回重造. 2020-08-06:将算法介绍进行扩写,并删除了一些可有可无的内容或玩梗内容. 管理员审核题解辛苦了. 简要题意 ...

  4. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  5. [UOJ317]【NOI2017】游戏 题解

    题意 ​ 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. ​ 小 L 的赛车有三辆,分别用大写字母 A.B.C 表示.地图一共有四种,分别用小写字 ...

  6. BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...

  7. noi2017 day1 题解

    d1t1 sol1:用线段树维护区间是否全0/全1,叶子上压位维护对应位置的数位,加法首先对叶子加,如需进位则向右找到第一个不是全1的叶子+1,中间部分全1部分打上反转标记,减法同理. #includ ...

  8. BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...

  9. BZOJ4942 & UOJ314:[NOI2017]整数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4942 http://uoj.ac/problem/314 https://www.luogu.or ...

随机推荐

  1. nginx 通过IP访问项目

    项目新需求,因为是小范围使用的网站,所以不打算配域名,直接通过IP访问当前项目. 环境: LNMP 一键集成环境 当前IP指向的目录 :/home/wwwroot/default/ 但是我的项目.需要 ...

  2. 齐博x1模板中常用的TP标签数据处理

    上图是比较常用的, 而下图是比较特殊的场合,比如幻灯片可能会用到 下图使用了TP的循环标签. 上图只使用了条件判断标签 上图不存在 val="xxx" 这个参数,所以会自动循环输出 ...

  3. 使用doctest代码测试和Sphinx自动生成文档

    python代码测试并自动生成文档 Tips:两大工具:doctest--单元测试.Sphinx--自动生成文档 1.doctest doctest是python自带的一个模块.doctest有两种使 ...

  4. [苹果APP上架]ios App Store上架详细教程-一条龙顺滑上架-适合小白

    如何在 2022 年将您的应用提交到 App Store 您正在启动您的第一个应用程序,或者距离上次已经有一段时间了.作者纸飞机@cheng716051来给你讲讲将应用程序提交到 App Store ...

  5. 学习Rust第一天 Rust语言特点

    学习Rust之前,我觉得应该首先了解Rust语言的设计目的是什么?为什么会诞生这门语言?这门语言和其他的语言有什么不同. Rust语言的设计特点 高性能:rust拥有和C++相近的性能表现,所以在嵌入 ...

  6. Codeforces Round #786 (Div. 3) 补题记录

    小结: A,B,F 切,C 没写 1ll 对照样例才发现,E,G 对照样例过,D 对照样例+看了其他人代码(主要急于看后面的题,能调出来的但偷懒了. CF1674A Number Transforma ...

  7. 抓包整理————ip 协议一[十二]

    前言 简单介绍一下ip协议. 正文 先来看下ip协议在网络层的哪一层: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 ip 层就在网络层: 其实很好想象哈,就是因为每台机器起码有一个ip ...

  8. js和jquery页面初始化加载函数的方法及顺序

    运行下面代码.弹出A.B.C.D.E的顺序:A=B=C>D=E. <html> <head> <title>首页</title> <scri ...

  9. MediatRPC - 基于MediatR和Quic通讯实现的RPC框架,比GRPC更简洁更低耦合,开源发布第一版

    大家好,我是失业在家,正在找工作的博主Jerry.作为一个.Net架构师,就要研究编程艺术,例如SOLID原则和各种设计模式.根据这些原则和实践,实现了一个更简洁更低耦合的RPC(Remote Pro ...

  10. i春秋xss平台

    点开是个普普通通的登录窗口,没有注册,只有登录,抓住包也没获取什么有用的信息,看了看dalao的wp才知道怎么做,首先抓包然后修改参数的定义来让其报错,pass原本的应该为整数,pass[]=就可以让 ...