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.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...
随机推荐
- Multiple Threads reading from the same file(转载)
问 I have a xml file that needs to be read from many many times. I am trying to use the Parallel.ForE ...
- Yarn 入门
Yarn 是快速.可靠.安全的 js 包管理器. 关键词: nodejs, 包管理, yarn 简介 Yarn 是快速.可靠.安全的 js 包管理器. 快速 - Yarn 会缓存它下载的每个包,所以无 ...
- CF932F Escape Through Leaf 斜率优化、启发式合并
传送门 \(DP\) 设\(f_i\)表示第\(i\)个节点的答案,\(S_i\)表示\(i\)的子节点集合,那么转移方程为\(f_i = \min\limits_{j \in S_i} \{a_i ...
- LiveCharts文档-3开始-1安装
原文:LiveCharts文档-3开始-1安装 LiveCharts文档-3开始-1安装 我不会逐字逐句翻译,有些过于基本的地方语言上会所略 三个平台我只翻译WinForm,其他的WPF和UWP大部分 ...
- Luogu P2279 [HNOI2003]消防局的设立
这真的是一道SB题.去你的树形DP 我们看到题目就开始考虑贪心,怎么搞? 一个显然的思路,每次找出一个深度最大且未被覆盖的点,然后建一个消防局? 但这样的话,动用简单的人类思维就可以知道:我TM的还不 ...
- 基于uFUN开发板的心率计(二)动态阈值算法获取心率值
前言 上一篇文章:基于uFUN开发板的心率计(一)DMA方式获取传感器数据,介绍了如何获取PulseSensor心率传感器的电压值,并对硬件电路进行了计算分析.心率计,重要的是要获取到心率值,本篇文章 ...
- Js把Json序列化为Java接受的对象。
服务器端 Java定义 data class role(var name: String = "", var remark: String = "") data ...
- java内存溢出的解决思路
原文地址:https://www.cnblogs.com/200911/p/3965108.html 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能 ...
- Jmeter(非GUI模式)教程
前言 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源.优点如下:1.节约系统资源:无需启动界面,节约系统资源 2.便捷快速:仅需启动命令行,输入命令便可执行 ...
- 几何学观止(Riemann流形部分)
上承这个页面,相较之前,增加了古典的曲线曲面论,这部分介绍得很扼要,Riemann流形介绍得也很快,花了仅仅30页就介绍到了Gauss-Bonnet公式.同时配上了提示完整的习题. 几何学观止-Rie ...