BZOJ.5312.冒险(线段树)
\(Description\)
维护一个序列,支持区间and/or一个数、区间查询最大值。
\(Solution\)
维护区间最大值?好像没什么用,修改的时候和暴力差不多。
我们发现有时候区间and/or对区间是没有影响的,有时候对区间所有数影响相同(都改变了某些位)。
比如区间and x,当\(sum_{or}\ and\ x==sum_{or}\)时,这个操作没有影响;
当区间所有数在x为1的位上相同,即x没有它们不共有的1,则可以直接打and/or标记,mx[rt] and/or= x。(\(sum_{and}\oplus sum_{or}\)就是区间内不共有的1)
(这个在and的时候也对啊,最大值and后还是>=其它数的。但是我还是写另一种方法吧。。即区间与和区间或修改后改变量都相同。)
在不满足这两个条件时继续递归子区间。
复杂度为\(O(nklogn)\),\(k\)为位数。证明参见:https://csacademy.com/contest/round-70/task/and-or-max/solution。(浏览器打不开 别的浏览器没插件就不看了)
另外区间and/or标记可以换成区间加标记。
//13528kb 4472ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=200005<<2;
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
int sand[N],sor[N],mx[N],tag[N];
#define Update(rt) sand[rt]=sand[ls]&sand[rs],sor[rt]=sor[ls]|sor[rs],mx[rt]=std::max(mx[ls],mx[rs])
void Build(int l,int r,int rt)
{
if(l==r) {sand[rt]=sor[rt]=mx[rt]=read(); return;}
Build(l,(l+r>>1),ls), Build((l+r>>1)+1,r,rs);
Update(rt);
}
inline void Upd(int rt,int v)
{
sand[rt]+=v, sor[rt]+=v, tag[rt]+=v, mx[rt]+=v;
}
inline void PushDown(int rt)//非叶
{
Upd(ls,tag[rt]), Upd(rs,tag[rt]), tag[rt]=0;
}
void Modify_And(int l,int r,int rt,int L,int R,int v)
{
if((sor[rt]&v)==sor[rt]) return;//==优先级比&,|高。。
if(L<=l && r<=R && (sand[rt]&v)-sand[rt]==(sor[rt]&v)-sor[rt])//!((sand[rt]^sor[rt])&v))//为什么不对呢。。
{
Upd(rt,(sand[rt]&v)-sand[rt]); return;
}
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m) Modify_And(lson,L,R,v);
if(m<R) Modify_And(rson,L,R,v);
Update(rt);
}
void Modify_Or(int l,int r,int rt,int L,int R,int v)
{
if((sand[rt]|v)==sand[rt]) return;
if(L<=l && r<=R && (sand[rt]|v)-sand[rt]==(sor[rt]|v)-sor[rt])//!((sand[rt]^sor[rt])&v))
{
Upd(rt,(sand[rt]|v)-sand[rt]); return;
}
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m) Modify_Or(lson,L,R,v);
if(m<R) Modify_Or(rson,L,R,v);
Update(rt);
}
int Query(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) return mx[rt];
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m)
if(m<R) return std::max(Query(lson,L,R),Query(rson,L,R));
else return Query(lson,L,R);
return Query(rson,L,R);
}
}T;
int main()
{
int n=read(),m=read();
T.Build(1,n,1);
for(int opt,l,r; m--; )
{
if((opt=read())==1) l=read(),r=read(),T.Modify_And(1,n,1,l,r,read());
else if(opt==2) l=read(),r=read(),T.Modify_Or(1,n,1,l,r,read());
else l=read(),r=read(),printf("%d\n",T.Query(1,n,1,l,r));
}
return 0;
}
BZOJ.5312.冒险(线段树)的更多相关文章
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- 【BZOJ 3476】 线段树===
59 懒惰的奶牛贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位.贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北.正东.正西.正南这四个 ...
- 【刷题】BZOJ 5312 冒险
Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...
- Luogu P1198 BZOJ 1012 最大数 (线段树)
手动博客搬家: 本文发表于20170821 14:32:05, 原地址https://blog.csdn.net/suncongbo/article/details/77449455 URL: (Lu ...
- bzoj 3585 mex - 线段树 - 分块 - 莫队算法
Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- BZOJ.3585.mex(线段树)
题目链接 题意:多次求区间\(mex\). 考虑\([1,i]\)的\(mex[i]\),显然是单调的 而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么 ...
- bzoj 4025 二分图——线段树分治+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...
随机推荐
- MySQL的备份和恢复-基于LVM快照的备份(lvm-snapshot)
MySQL的备份和恢复-基于LVM快照的备份(lvm-snapshot) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是快照卷 如上图所示,原卷和快照卷可以不一样大,因为 ...
- OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型
OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...
- C#的Lamda表达式_匿名函数
- 20155203 2016-2017-2 《Java程序设计》第7周学习总结
20155203 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 1.Lambda表达式.(使用interface函数接口) 2.Lambda的方法参考Met ...
- Hive笔记之Fetch Task
在使用Hive的时候,有时候只是想取表中某个分区的前几条的记录看下数据格式,比如一个很常用的查询: select * from foo where partition_column=bar limit ...
- 使用sp_executesql
建议您在执行字符串时,使用 sp_executesql 存储过程而不要使用 EXECUTE 语句.由于此存储过程支持参数替换,因此 sp_executesql 比 EXECUTE 的功能更多:由于 S ...
- EM算法理解
一.概述 概率模型有时既含有观测变量,又含有隐变量,如果概率模型的变量都是观测变量,那么给定数据,可以直接利用极大似然估计法或者贝叶斯估计法估计模型参数.但是,当模型同时又含有隐变量时,就不能简单地使 ...
- 关于USBHID协议以及鼠标键盘描述符的解释【转】
转自:https://blog.csdn.net/jiujiujiuqiuqiuqiu/article/details/47277685 一.HID设备识别 前面有提到关于SCSI协议的USB设备实现 ...
- IE WebBrowser内核设置
public class IEVersion { /// <summary> /// IE WebBrowser内核设置 /// </summary> public stati ...
- oracle列转行
unpivot()函数需要Oracle版本大于等于11g --创建表 create table Fruit(id int,name varchar(20), Q1 int, Q2 int, Q3 in ...