题目链接

\(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.冒险(线段树)的更多相关文章

  1. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  2. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  3. 【BZOJ 3476】 线段树===

    59  懒惰的奶牛贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位.贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北.正东.正西.正南这四个 ...

  4. 【刷题】BZOJ 5312 冒险

    Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...

  5. Luogu P1198 BZOJ 1012 最大数 (线段树)

    手动博客搬家: 本文发表于20170821 14:32:05, 原地址https://blog.csdn.net/suncongbo/article/details/77449455 URL: (Lu ...

  6. bzoj 3585 mex - 线段树 - 分块 - 莫队算法

    Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...

  7. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  8. BZOJ.3585.mex(线段树)

    题目链接 题意:多次求区间\(mex\). 考虑\([1,i]\)的\(mex[i]\),显然是单调的 而对于\([l,r]\)与\([l+1,r]\),如果\(nxt[a[l]]>r\),那么 ...

  9. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

随机推荐

  1. javaweb购物车实现的几种方式

    之前没有接触过购物车的东东,也不知道购物车应该怎么做,所以在查询了很多资料,总结一下购物车的功能实现. 查询的资料,找到三种方法: 1.用cookie实现购物车: 2.用session实现购物车: 3 ...

  2. 数据库类型与JDBC TYPE 和Java类型对应关系

    https://blog.csdn.net/seelye/article/details/40105969

  3. HDU 3595 every-sg模型

    多个子游戏同时进行,每个子游戏给出两个数a,b,可以将大的数减去k倍小的数,不能操作者输. 策略就是对于一个必胜的游戏要使得步数更长,对于一个必败的游戏使得步数最短. 以下都来自贾志豪的论文.. 对于 ...

  4. pgadmin导出excel

    生成导入sql 第一行公式:="insert into province(code,name) values("&A2&",'"&B2& ...

  5. java学习第05天(数组常见操作、数组中的数组)

    (4)数组常见操作 a.遍历取值 class ArrayDemo3 { public static void main(String[] args) { //System.out.println(&q ...

  6. HDU 4502 吉哥系列故事——临时工计划(一维动态规划)

    题意:吉哥的假期是1到n天,然后有m个工作可以让吉哥选择做,每个工作都有一个开始 t_s  和结束的时间   t_e ,都用天来表示,然后每个工作必须从第一天做到最后一天, 从头到尾做完之后就可以得到 ...

  7. vue实战之狗血事件:页面loading效果诡异之事

    接上回 想加一个切换路由时,跳出一个loading动画 ,路由加载后就消失 先做了一个loading提示的浮动层的组件,全局注册,在几个路由页面都引入 在vuex里面维护一个变量比如isLoading ...

  8. golang container heap&sort

    go语言也自己的容器数据结构.主要有list.heap和ring package main import ( "container/heap" "fmt" &q ...

  9. Linux USB Host-Controller的初始化代码框架分析【转】

    转自:http://blog.csdn.net/zkami/article/details/2496770 usb_hcd_omap_probe (const struct hc_driver *dr ...

  10. Project Euler Problem5

    Smallest multiple Problem 5 2520 is the smallest number that can be divided by each of the numbers f ...