BZOJ题目传送门

表示蒟蒻并不能一眼看出来这是个势能线段树。

不过仔细想想也并非难以理解,感性理解一下,在一个区间里又与又或,那么本来不相同的位也会渐渐相同,线段树每个叶子节点最多修改\(\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 冒险(势能线段树)的更多相关文章

  1. BZOJ5312: 冒险【线段树】【位运算】

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

  2. BZOJ5312 冒险(线段树)

    记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...

  3. 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)

    线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...

  4. 洛谷P4891 序列(势能线段树)

    洛谷题目传送门 闲话 考场上一眼看出这是个毒瘤线段树准备杠题,发现实在太难调了,被各路神犇虐哭qwq 考后看到各种优雅的暴力AC......宝宝心里苦qwq 思路分析 题面里面是一堆乱七八糟的限制和性 ...

  5. Can you answer these queries?(HDU4027+势能线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 题目: 题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和. 思路:易 ...

  6. 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 ...

  7. BZOJ5312 冒险 势能分析、线段树

    传送门 区间位赋值.区间求最大值似乎是不能够像一般的线段树一样直接打标记的,但是直接暴力也太没有面子了. 我们考虑优化一下暴力:如果说线段树的一段区间内在当前修改的所有位置上所有数都是相同的,那么这个 ...

  8. bzoj5312: 冒险(势能均摊线段树)

    题目链接 BZOJ5312: 冒险 题解 如果一次操作对区间& 和 区间| 产生的影响是相同的,那么该操作对整个区间的影响都是相同的 对于每次操作,在某些位上的值,对于整个区间影响是相同的,对 ...

  9. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

随机推荐

  1. .Net Core 系列之一 hello world

    OS: win10 企业版 中文环境 .Net Core: 切记不要装64版本,否则可能会出现vs2017无法生成.net core 2.0的项目 dotnet-sdk-2.0.0-win-x86.e ...

  2. mysql中Error : Invalid default value for 'timestamp'问题

    在执行mysql数据库时报错       timestamp给默认值出问题. 原因是:mysql的配置参数中sql_node中NO_ZERO_IN_DATE, NO_ZERO_DATE控制了times ...

  3. Luogu P4053 [JSOI2007]建筑抢修

    一道贪心题,看数据范围就知道要套一个数据结构上去. 别走啊不是什么很高级的数据结构 考虑最朴素的想法,按建筑的抢修时间排序并先拿小的 然后随便想想都可以找到一堆反例 所以我们就直接考虑模拟这个过程,按 ...

  4. Luogu P3990 [SHOI2013]超级跳马

    这道题还是一道比较不可做的矩阵题 首先我们先YY一个递推的算法:令f[i][j]表示走到第i行第j列时的方案数,那么有以下转移: f[i][j]=f[i-1][j-2*k+1]+f[i+1][j-2* ...

  5. C# 调用微信接口上传素材和发送图文消息

    using Common;using Newtonsoft.Json.Linq;using System;using System.IO;using System.Net;using System.T ...

  6. 小白学Docker之基础篇

    系列文章: 小白学Docker之基础篇 小白学Docker之Compose 小白学Docker之Swarm PS: 以下是个人作为新手小白学习docker的笔记总结 1. docker是什么 百科上的 ...

  7. 五年.net程序员Java学习之路

    大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...

  8. c#基础系列3---深入理解ref 和out

    "大菜":源于自己刚踏入猿途混沌时起,自我感觉不是一般的菜,因而得名"大菜",于自身共勉. 扩展阅读 c#基础系列1---深入理解 值类型和引用类型 c#基础系 ...

  9. LVM : 扩展文件系统的容量

    如果发现文件系统的容量不足了,可以通过 LVM 轻松的进行扩展(当然也可以进行缩减操作).本文将紧接前文中的 demo 详细的介绍扩展文件系统的操作过程.说明:本文的演示环境为 ubuntu 16.0 ...

  10. Webpack 2 视频教程 004 - Webpack 初体验

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...