BZOJ5312:冒险——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5312
Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题,只有答对了问题才能进入,守护神给出了一个自然数序列a,每次有一下三种操作。1,给出l,r,x,将序列l,r之间的所有数都 and x2,给出l,r,x,将序列l,r之间的所有数都 or x3,给出l,r,询问l,r之间的最大值
(下划线以前都是废话)
没有什么好方法,因为最大值的变化不能用简单的and x以及or x,但是我们能够暴力线段树维护,然而毫无疑问是TLE。
于是我们的目标是直接能够mx[a]and/or=x以此维护。
我们考虑能不能用吉司机线段树维护一下。
让我们想一个naive的想法,即我and x则区间全变成x,or x则区间全变成x。
于是我们需要多记录两个区间and值和区间or值,如果区间and值and x=x则我们全变x,如果区间or值or x=x则我们全变x。
当然会TLE……
————————————————————————
我们继续想,区间内的数在经过多次操作后其公共的1的数量占每个数的1的个数的比重会越来越大并最终为100%。
于是我们要利用这个想法,当然这里给出结论:(区间or值xor区间and值)and x=0时我们更新。
(括号内的东西代表了各数的不公有的1,也就是说x不能有它们不公有的1,剩下的还请读者自行推导其正确性。)
此时mx[a]and/or=x即可(显然的),同时我们还可对区间and值和or值也and/or=x来更新(不显然,但懒得证了)。
现在就很像吉司机线段树了,但是对于势能分析我要写个大大的坑字在这里。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=(<<)-;
const int N=2e5+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int n,m,b[N],mx[N*],ran[N*],ror[N*],lza[N*],lzo[N*];
inline void upt(int a){
mx[a]=max(mx[a<<],mx[a<<|]);
ran[a]=ran[a<<]&ran[a<<|];
ror[a]=ror[a<<]|ror[a<<|];
}
void build(int a,int l,int r){
lza[a]=INF,lzo[a]=;
if(l==r){
mx[a]=b[l];ran[a]=b[l];ror[a]=b[l];
return;
}
int mid=(l+r)>>;
build(a<<,l,mid);build(a<<|,mid+,r);
upt(a);
}
inline void push(int a){
int ls=a<<,rs=a<<|;
if(lzo[a]!=){
mx[ls]|=lzo[a];mx[rs]|=lzo[a];
ran[ls]|=lzo[a];ran[rs]|=lzo[a];
ror[ls]|=lzo[a];ror[rs]|=lzo[a];
lza[ls]|=lzo[a];lza[rs]|=lzo[a];
lzo[ls]|=lzo[a];lzo[rs]|=lzo[a];
lzo[a]=;
}
if(lza[a]!=INF){
mx[ls]&=lza[a];mx[rs]&=lza[a];
ran[ls]&=lza[a];ran[rs]&=lza[a];
ror[ls]&=lza[a];ror[rs]&=lza[a];
lza[ls]&=lza[a];lza[rs]&=lza[a];
lza[a]=INF;
}
}
void mdy(int a,int l,int r,int l1,int r1,int x,bool k){
if(r<l1||r1<l)return;
if(l1<=l&&r<=r1&&(!((ran[a]^ror[a])&x))){
if(!k){mx[a]&=x;ran[a]&=x;ror[a]&=x;lza[a]&=x;}
else{mx[a]|=x;ran[a]|=x;ror[a]|=x;lza[a]|=x;lzo[a]|=x;}
return;
}
int mid=(l+r)>>;
push(a);
mdy(a<<,l,mid,l1,r1,x,k);mdy(a<<|,mid+,r,l1,r1,x,k);
upt(a);
}
int qry(int a,int l,int r,int l1,int r1){
if(r<l1||r1<l)return -;
if(l1<=l&&r<=r1)return mx[a];
int mid=(l+r)>>;
push(a);
return max(qry(a<<,l,mid,l1,r1),qry(a<<|,mid+,r,l1,r1));
}
int main(){
n=read(),m=read();
for(int i=;i<=n;i++)b[i]=read();
build(,,n);
while(m--){
int op=read(),x=read(),y=read();
if(op==)mdy(,,n,x,y,read(),);
if(op==)mdy(,,n,x,y,read(),);
if(op==)printf("%d\n",qry(,,n,x,y));
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5312:冒险——题解的更多相关文章
- bzoj5312: 冒险(势能均摊线段树)
题目链接 BZOJ5312: 冒险 题解 如果一次操作对区间& 和 区间| 产生的影响是相同的,那么该操作对整个区间的影响都是相同的 对于每次操作,在某些位上的值,对于整个区间影响是相同的,对 ...
- bzoj5312 冒险(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 按位与\(x\) \(2.\)区间\([L,R]\) 按位或\(x\) \(3.\)区间\([L,R]\) 询问最大值 ...
- BZOJ5312 冒险(线段树)
记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...
- BZOJ5312: 冒险【线段树】【位运算】
Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...
- BZOJ5312 冒险(势能线段树)
BZOJ题目传送门 表示蒟蒻并不能一眼看出来这是个势能线段树. 不过仔细想想也并非难以理解,感性理解一下,在一个区间里又与又或,那么本来不相同的位也会渐渐相同,线段树每个叶子节点最多修改\(\log ...
- [BZOJ5312]冒险
bzoj CSAcademy description 一个序列\(a_i\),支持区间与一个数,区间或一个数,求区间最大值. \(n,m\le2\times10^5\) sol 线段树每个节点上维护区 ...
- bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence
算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...
- BZOJ5312 冒险 势能分析、线段树
传送门 区间位赋值.区间求最大值似乎是不能够像一般的线段树一样直接打标记的,但是直接暴力也太没有面子了. 我们考虑优化一下暴力:如果说线段树的一段区间内在当前修改的所有位置上所有数都是相同的,那么这个 ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
随机推荐
- MySQL高级-性能分析Explain
1.使用Explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的.分析你的查询语句或是表结构的性能瓶颈 . 2.执行方法:Explain + SQL语句 解释 ...
- java 多维数组转化为字符串
int[][] a = {{1,2,3},{4,5,7}}; System.out.println(Arrays.deepToString(a)); Arrays.deepToString()此方法是 ...
- OSG-CompositeViewer
原文连接地址:http://www.osgchina.org/index.php?Itemid=490&id=134:usecompositiv&option=com_content& ...
- Linux命令应用大词典-第38章 网络命令
38.1 traceroute:显示跟踪到网络主机的路由数据包 38.2 mli-tool:查看.操纵网络接口状态 38.3 ifconfig:显示和配置网络接口 38.4 ifdown:关闭网络接口 ...
- Linux命令应用大词典-第32章 性能监控
32.1 sar:收集.报告或保存系统活动信息 32.2 iostat:报告CPU统计数据和设备.分区输入.输出消息 32.3 iotop:进行I/O监控 32.4 mpstat:报告CPU相关的统计 ...
- Soliworks 2016建模细节总结(1)
Soliworks 2016建模小细节总结(1) 1.Solidworks 2016三维建模的时候,如果想要在一个视图里面呈现出四个视图(包括三个独立的视图以及三维结构的实体模型图),可以直接按鼠标会 ...
- JavaScript 常用正则示例
1. trim功能(清除字符串两端空格) String.prototype.trim = function() { return this.replace(/(^\s+)|(\s+$)/g, '') ...
- Caching Data in the Architecture (C#)
http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-in-the-architecture-cs ...
- Ubuntu14.04下部署FastDFS 5.08+Nginx 1.9.14
最新的版本可以在这里获取,目前下载的最新版本是5.08,更新于2016-02-03.在这里可以找到更多的说明. 下载好后,server端分为两个部分,一个是tracker,一个是storage.顾 ...
- Nodejs中关于模块的总结
关于Nodejs中的模块 概念 Nodejs在ECMAScript的基础上扩展并封装了许多高级特性,如文件访问.网络访问等,使得Nodejs成为一个很好的Web开发平台.基于Nodejs这个平台将We ...