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.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...
随机推荐
- vue 动态创建组件(运行时创建组件)
function mountCmp (cmp, props, parent) { if (cmp.default) { cmp = cmp.default } cmp = Vue.extend(cmp ...
- python 的zip 函数小例子
In [57]: name = ('Tome','Rick','Stephon') In [58]: age = (45,23,55) In [59]: for a,n in zip (name,ag ...
- JVM规范系列第1章:引言
如果你还没下载<Java虚拟机规范>这本书,那么先点击这里下载再一块儿看吧. 前言 Java 虚拟机是一个抽象化的机器,整个规范中提及的 Java 虚拟机都是抽象化的概念,而不是特指 Or ...
- 【JVM.5】类文件结构
鲁迅曾经说过:代码编译的结构从本地机器码转变为字节码,是存储格式发展的一小步,确是编程语言发展的一大步. 一.无关性的基石 Java设计者在最初就承诺过“In the future, we will ...
- Mongodb副本集+分片集群环境部署记录
前面详细介绍了mongodb的副本集和分片的原理,这里就不赘述了.下面记录Mongodb副本集+分片集群环境部署过程: MongoDB Sharding Cluster,需要三种角色: Shard S ...
- 附加题(一)——interesting的抄袭现象
这次的作业很有意思,是让我们搜索抄袭的同学的个人总结,并让我们列出链接,时间,作者及原因.其实我不是很能理解,抄袭现象是可耻的不受推崇的这是无可厚非,但是为什么要求我们大部分没有抄袭的同学去探究抄袭同 ...
- 删除运行时权限不足,cmd开启管理员
管理员帐号活跃代码:net user administrator /active:yes 搜索cmd-右键以管理员身份运行 切换administrator帐号登录 操作后最后关闭这么高的权限,避免被非 ...
- Mybatis Update statement Date null
Mybatis Update statement Date null 只要在Model里把字段置为java的null即可.
- redux的源码解析
一. redux出现的动机 1. Javascript 需要管理比任何时候都要多的state2. state 在什么时候,由于什么原因,如何变化已然不受控制.3. 来自前端开发领域的新需求4. 我们总 ...
- php实现常驻进程 多进程监控
php都是通过crontabd定时脚本处理队列的,面试被问到php如何常驻进程进行处理队列,想了半天这样不知道是否是一种方式 <?php function logs(){ file_put_co ...