BZOJ5312 冒险(势能线段树)
表示蒟蒻并不能一眼看出来这是个势能线段树。
不过仔细想想也并非难以理解,感性理解一下,在一个区间里又与又或,那么本来不相同的位也会渐渐相同,线段树每个叶子节点最多修改\(\log a\)次(\(a\)为值域)。
那么,我们做区间修改的时候,进行判断:如果这一次修改对区间里所有数的影响都是一样的,那么直接在当前位置放懒标记。
如何判断呢?又是一个位运算技巧:维护区间与和区间或,两者的异或即为区间内存在不同的位集。那么只有这些位集不会被与上0、或上1,才可以放懒标记。
至于又与又或很麻烦,我们定义标记\((la,lo)\)表示整个区间都&la
再|lo
。
标记的合并手推一下就好了,\((la,lo)+(na,no)=(la\&na,lo\&na|no)\)
复杂度\(n\log n\log a\),果然维护的东西一多数组版线段树的常数就大起来了。。。
#include<bits/stdc++.h>
#define RG register
#define R RG int
#define G if(++ip==ie)fread(ip=buf,1,N,stdin)
using namespace std;
const int N=1<<19,S=(1<<21)-1;
char buf[N],*ie=buf+N,*ip=ie-1;
int na,no,sa[N],so[N],la[N],lo[N],mx[N];
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
#define Pushup \
sa[x]=sa[lc]&sa[rc]; \
so[x]=so[lc]|so[rc]; \
mx[x]=max(mx[lc],mx[rc])
#define Pushdn \
if(la[x]!=S||lo[x]){ \
pusht(lc,la[x],lo[x]); \
pusht(rc,la[x],lo[x]); \
la[x]=S;lo[x]=0; \
}
inline void pusht(R x,R a,R o){//合并标记并更新信息
la[x]&=a;(lo[x]&=a)|=o;
(so[x]&=a)|=o;(sa[x]&=a)|=o;(mx[x]&=a)|=o;
}
void build(R x,R l,R r){
la[x]=S;
if(l==r){
mx[x]=sa[x]=so[x]=in();return;
}
R m=(l+r)>>1,lc=x<<1,rc=lc|1;
build(lc,l,m);build(rc,m+1,r);
Pushup;
}
void upd(R x,R l,R r,R s,R e){
if(l==s&&r==e&&!((sa[x]^so[x])&(~na|no)))//判断是否影响一致
return pusht(x,na,no);
R m=(l+r)>>1,lc=x<<1,rc=lc|1;
Pushdn;
if(e<=m)upd(lc,l,m,s,e);
else if(s>m)upd(rc,m+1,r,s,e);
else upd(lc,l,m,s,m),upd(rc,m+1,r,m+1,e);
Pushup;
}
int qry(R x,R l,R r,R s,R e){
if(l==s&&r==e)return mx[x];
R m=(l+r)>>1,lc=x<<1,rc=lc|1;
Pushdn;
if(e<=m)return qry(lc,l,m,s,e);
if(s>m)return qry(rc,m+1,r,s,e);
return max(qry(lc,l,m,s,m),qry(rc,m+1,r,m+1,e));
}
int main(){
R n=in(),m=in(),op,l,r;
build(1,1,n);
while(m--){
op=in();l=in();r=in();
if(op==1)na=in(),no=0,upd(1,1,n,l,r);//或上0还是原来的数
if(op==2)na=S,no=in(),upd(1,1,n,l,r);//与上全1还是原来的数
if(op==3)printf("%d\n",qry(1,1,n,l,r));
}
return 0;
}
BZOJ5312 冒险(势能线段树)的更多相关文章
- BZOJ5312: 冒险【线段树】【位运算】
Description Kaiser终于成为冒险协会的一员,这次冒险协会派他去冒险,他来到一处古墓,却被大门上的守护神挡住了去路,守护神给出了一个问题, 只有答对了问题才能进入,守护神给出了一个自然数 ...
- BZOJ5312 冒险(线段树)
记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- 洛谷P4891 序列(势能线段树)
洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...
- Can you answer these queries?(HDU4027+势能线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题目: 题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和. 思路:易 ...
- CodeForces - 438D: The Child and Sequence(势能线段树)
At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at ...
- BZOJ5312 冒险 势能分析、线段树
传送门 区间位赋值.区间求最大值似乎是不能够像一般的线段树一样直接打标记的,但是直接暴力也太没有面子了. 我们考虑优化一下暴力:如果说线段树的一段区间内在当前修改的所有位置上所有数都是相同的,那么这个 ...
- bzoj5312: 冒险(势能均摊线段树)
题目链接 BZOJ5312: 冒险 题解 如果一次操作对区间& 和 区间| 产生的影响是相同的,那么该操作对整个区间的影响都是相同的 对于每次操作,在某些位上的值,对于整个区间影响是相同的,对 ...
- BZOJ4695 最假女选手(势能线段树)
BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...
随机推荐
- linux驱动编写之中断处理
一.中断 1.概念 学过单片机的应该非常清楚中断的概念,也就是CPU在正常执行程序过程中,出现了突发事件(中断事件),于是CPU暂停当前程序的执行,转去处理突发事件.处理完毕后,CPU又返回被中断的程 ...
- C#的delegate简单练习
delegate中文的意思为委托. 在很久之前,Insus.NET有写过一篇<用一个简单的例子来演绎事件委托>http://www.cnblogs.com/insus/p/3732075. ...
- Artificial Intelligence Computing Conference(2018.09.12)
时间:2018.09.12地点:北京国际饭店会议中心
- flask-socketio笔记
Flask-SocketIO使Flask应用程序可以访问客户端和服务器之间的低延迟双向通信. 客户端应用程序可以使用Javascript,C ++,Java和Swift中的任何SocketIO官方客户 ...
- DNS之BIND使用小结(Forward转发)
之前详细介绍了DNS及其在linux下的部署过程,今天再说下DNS的BIND高级特性-forwarder转发功能.比如下面一个案例:1)已经在测试环境下部署了两台内网DNS环境,DNS的zone域名为 ...
- 移动端触摸(touch)事件
移动端时代已经到来,作为前端开发的我们没有理由也不应该坐井观天,而是勇敢地跳出心里的那口井,去拥抱蔚蓝的天空.该来的总会来,我们要做的就是接受未知的挑战.正如你所看到的,这是一篇关于移动端触摸事件的文 ...
- 个人阅读作业Week5
一.总结体会 团队项目已经进行了很多周,我们团队从刚开始的基础薄弱到现在的大家都可以运用Android来编写程序,共同完成一个app的开发使用. 刚开始做团队项目之时,我们团队就开了一个会,确定了以后 ...
- Balanced Ternary String CodeForces - 1102D (贪心+思维)
You are given a string ss consisting of exactly nn characters, and each character is either '0', '1' ...
- C#改变图片大小
今天一女同事要做一个改变图片大小的功能,然后我就手写了几行代码,以后可能用得上 byte[] buffer = new byte[1]; //Byte转为Image对象 MemoryStream ms ...
- MSA微服务
https://github.com/das2017?tab=repositories https://github.com/icsharpcode/ILSpy/releases LayerDemo ...