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 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...
随机推荐
- Tomcat权威指南-读书摘要系列10
Tomcat集群 一些集群技术 DNS请求分配 TCP网络地址转换请求分配 Mod_proxy_balance负载均衡与故障复原 JDBC请求分布与故障复原
- 引用EChart和Bootstrap
1.怎么引用Echart 下载之后,写一个html,里面这样写 <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- web html 基础2
1.表格<table> 行 tr,没有列的说法,只是单元格td table里面只能仿tr,tr里面只能放td,td可以嵌套任何标签 表格属性 border 边框, cellspacing ...
- .NET面试题系列(三)排序算法
冒泡排序 , , , , , 7, 2, 4 }; //外层循环控制排序趟数 ; i < arr.Length - ; i++) { //内层循环控制每一趟排序多少次 ; j < arr. ...
- Javascript非构造函数的继承
一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...
- Value = undefined
Value = undefined Javascript在计算机程序中,经常会声明无值的变量.未使用值来声明的变量,其值实际上是 undefined. 在执行过以下语句后,变量 carname 的值将 ...
- 图的最短路径-----------SPFA算法详解(TjuOj2831_Wormholes)
这次整理了一下SPFA算法,首先相比Dijkstra算法,SPFA可以处理带有负权变的图.(个人认为原因是SPFA在进行松弛操作时可以对某一条边重复进行松弛,如果存在负权边,在多次松弛某边时可以更新该 ...
- golang的sort研究
年前没钱,等发工资.就这么在公司耗着不敢回家,无聊看了下golang的sort源码 type Interface interface { // Len is the number of element ...
- arm GIC介绍之一【转】
转自:https://blog.csdn.net/sunsissy/article/details/73791470 GIC是ARM架构中及其重要的部分,本文只在公开ARM对应资料基础上,以MTK开发 ...
- centos6 安装EPEL
一.安装 32位系统: rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm rpm --i ...