Segment Tree Beats 区间最值问题

线段树一类特殊技巧!

引出:CF671C Ultimate Weirdness of an Array

其实是考试题,改题的时候并不会区间取最值,区间求和,之后秉承着好好学习的态度,学习了Segment tree Beats

套路是维护出区间最小值和次小值,以及区间最小值数量。之后再维护出题目中需要的东西就好了。之后怎么处理呢,如果我们需要维护出区间和x取max,那么,如果x<=minn[rt],那么直接return;如果x<minx[rt](minx[rt]为区间次小值),那么之间将最小值改成x,之后再改需要改的信息就好了...但是,如果x>=minx[rt],那么就递归处理子树信息。

什么?你说它的时间复杂度?每次修改均摊O(nlogn)

什么时候修改是O(n)呢,就是所有点的状态大概接近于1,2,1,2,1,2,1,2,1,2...之后对3取max,这种情况下单次修改是O(n)的,但是修改完这次之后,不论下一次修改是什么,都是O(1)的,并且,求和不会超过O(nlogn)

其实本质上,什么拖累了时间复杂度呢?就是当区间中不同的元素特别多的时候,单次修改的时间复杂度会较为高昂,但是假设,我们修改了A个元素,那么就相当于区间的集合中少了A-1个元素,并且我们知道这次修改最大是Alogn的,那么下一次修改就相当于少了A-1个不同元素,也就是说,假设没有这次修改,下一次修改B个元素的话,那么有了这次修改下一次就相当于修改了B-A+1个元素,那么我们考虑将所有的修改操作的时间复杂度求和,接近于O(nlogn),但是,这并不完全,因为每次修改可能会导致某些区间的元素个数增加。那么我们考虑会增加多少呢?因为所有修改的元素都修改成了一个值,那么就相当于有些区间的元素的个数多了1。那么修改的时间复杂度就是期望上(Qlogn+nlogn),但是其实并不会跑满,而且实际效率很快。

那么线段树的题嘛,考虑加上区间修改等操作的时间复杂度。因为每次区间覆盖的话,非常棒,取消了许多节点的独立性,时间复杂度完全没有问题!但是区间加的话假如一个区间的是1,2,3,4,5,6,1,2,3,4,5,6之后针对前6个区间加6,那么相当于增加了一倍的独立点个数,但是反过来考虑,构成1,2,3,4,5,6,1,2,3,4,5,6需要这种特殊构造,而特殊构造耗费的操作数量是接近n级别的,那么其实反过来考虑一下,时间复杂度没有任何问题,因为,其实我们考虑,只有区间修改的时间复杂度,是logn,那么为什么是O(logn)的原因是因为打了lazy标记,那么其实我们假装这里打了一个lazy标记,那么其实每次修改的节点只有log级别的,那么其实A也只增加了log级别的存在,而每次PushDown增加的也只是logn*Alogn其实也就是Alognlogn的时间复杂度。这非常正确,请不要反驳我。

那么我们考虑完时间复杂度了,是不是该讲题了?

并不是,因为例题没有那么多...

那么我们先举一个例子

给定一个长度为n的数列A,接下来有m次操作:

• 区间[l,r]中的所有数变成min(Ai,x)

• 询问区间[l,r]中所有数的和

• n,m≤50000 分块!(抱歉,我不会!)

• n,m ≤ 500000

裸题,按照上述要求维护一下就可以了,如果想写的话,可以联系我,我这里有我自己出的数据...

给定一个长度为n的数列A,接下来有m次操作:

• 区间[l,r]中的所有数变成min(Ai,x)

• 区间[l,r]中的所有数加上x(x可能是负数)

• 询问区间[l,r]中所有数的和

• n,m≤50000  分块!

• n,m ≤ 500000

同样是裸题,多了一个操作,HDU上有...题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5306

剩下的就是例题时间了!

BZOJ4355: Play with sequence

这个是不是有一点感觉了呢?

分析:其实还是区间操作裸题,我们对于操作1,之间区间覆盖,对于操作2先区间加,再区间取max...其实并不是很难对不对?对于操作3,之间输出1-n的最小值个数(如果最小值是0的话)

附上代码:

#include <queue>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 300505
#define ls rt<<1
#define rs rt<<1|1
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll minn[N<<2],minx[N<<2],cn[N<<2],cov[N<<2],add[N<<2];int n,Q;
void PushUp(int rt)
{if(minn[ls]<minn[rs])minn[rt]=minn[ls],minx[rt]=min(minn[rs],minx[ls]),cn[rt]=cn[ls];else if(minn[ls]==minn[rs])minn[rt]=minn[ls],minx[rt]=min(minx[rs],minx[ls]),cn[rt]=cn[ls]+cn[rs];else minn[rt]=minn[rs],minx[rt]=min(minn[ls],minx[rs]),cn[rt]=cn[rs];
}
void PushDown(int m,int rt)
{if(cov[rt]!=-1)minn[rs]=minn[ls]=cov[ls]=cov[rs]=cov[rt],cn[ls]=(m-(m>>1)),cn[rs]=(m>>1),minx[ls]=minx[rs]=1ll<<62,add[ls]=add[rs]=0,cov[rt]=-1;if(add[rt])minn[ls]+=add[rt],minn[rs]+=add[rt],minx[ls]+=add[rt],minx[rs]+=add[rt],add[ls]+=add[rt],add[rs]+=add[rt],add[rt]=0;if(minn[rt]>minn[ls])minn[ls]=minn[rt];if(minn[rt]>minn[rs])minn[rs]=minn[rt];
}
void build(int l,int r,int rt)
{cov[rt]=-1,add[rt]=0;if(l==r){scanf("%lld",&minn[rt]),minx[rt]=1ll<<62,cn[rt]=1;return;}int m=(l+r)>>1;build(lson);build(rson);PushUp(rt);
}
void Update_cov(int L,int R,ll c,int l,int r,int rt)
{if(L<=l&&r<=R){minn[rt]=cov[rt]=c,minx[rt]=1ll<<62,cn[rt]=r-l+1,add[rt]=0;return;}PushDown(r-l+1,rt);int m=(l+r)>>1;if(L<=m)Update_cov(L,R,c,lson);if(m<R)Update_cov(L,R,c,rson);PushUp(rt);
}
void Update_add(int L,int R,ll c,int l,int r,int rt)
{if(L<=l&&r<=R){minn[rt]+=c,add[rt]+=c,minx[rt]+=c;return;}PushDown(r-l+1,rt);int m=(l+r)>>1;if(L<=m)Update_add(L,R,c,lson);if(m<R)Update_add(L,R,c,rson);PushUp(rt);
}
void Update_max(int L,int R,ll c,int l,int r,int rt)
{if(c<=minn[rt])return ;if(L<=l&&r<=R&&minx[rt]>c){minn[rt]=c;return ;}PushDown(r-l+1,rt);int m=(l+r)>>1;if(L<=m)Update_max(L,R,c,lson);if(m<R)Update_max(L,R,c,rson);PushUp(rt);
}
ll query(int L,int R,int l,int r,int rt)
{if(L<=l&&r<=R)return minn[rt]?0:cn[rt];PushDown(r-l+1,rt);int m=(l+r)>>1;ll ret=0;if(L<=m)ret+=query(L,R,lson);if(m<R)ret+=query(L,R,rson);return ret;
}
int main()
{scanf("%d%d",&n,&Q);build(1,n,1);while(Q--){int x,y,op;ll z;scanf("%d%d%d",&op,&x,&y);if(op==1)scanf("%lld",&z),Update_cov(x,y,z,1,n,1);else if(op==2)scanf("%lld",&z),Update_add(x,y,z,1,n,1),Update_max(x,y,0ll,1,n,1);else printf("%lld\n",query(x,y,1,n,1));}return 0;
}

  好吧好吧...其实例题目前只有一道...目测还有最假女选手什么的...好麻烦的说...

转载于:https://www.cnblogs.com/Winniechen/p/9184912.html

Segment Tree Beats 区间最值问题相关推荐

  1. BZOJ.4695.最假女选手(线段树 Segment tree Beats!)

    题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...

  2. [学习笔记]Segment Tree Beats!九老师线段树

    对于这样一类问题: 区间取min,区间求和. N<=100000 要求O(nlogn)级别的算法 直观体会一下,区间取min,还要维护区间和 增加的长度很不好求.... 然鹅, 从前有一个来自杭 ...

  3. 【牛客NOIP模拟】牛半仙的妹子序列【DP】【Segment Tree Beats】

    题意:排列的极长上升子序列个数 n≤2×105n\leq 2\times 10^5n≤2×105 显然有个 dp fn=∑i<n,pi<pn,∄i<j<ns.t. pi< ...

  4. 【bzoj4355】Play with sequence 线段树区间最值操作

    题目描述 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C. 2)给出参数U,V,C,对于区间[U,V]里的每个数 ...

  5. 【bzoj4695】最假女选手 线段树区间最值操作

    题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作: 1.给一个区间[L,R] 加上一个数x  2.把一个区间[L,R] 里小于x 的数变成x  3.把一个区间[L,R] ...

  6. codeforces EDU segment tree

    本文以codeforces EDU segment tree为资料 content introdcution problems & solutions A. Sign alternation ...

  7. BZOJ-4811: [Ynoi2017]由乃的OJ (树链剖分 线段树维护区间操作值 好题)

    4811: [Ynoi2017]由乃的OJ Time Limit: 6 Sec  Memory Limit: 256 MB Submit: 366  Solved: 118 [Submit][Stat ...

  8. 区间最值操作与历史最值问题(一)

    前言 本文主要讲解一种叫做 SegmentTreeBeatsSegmentTree~BeatsSegmentTree Beats 的维护区间取最值操作的问题,以及维护区间历史最值的方法.本文参考自许多 ...

  9. 【ULR #2】Picks loves segment tree IX

    调吐了-- 题目描述 太长了,所以就不写了,直接贴链接Picks loves segment tree IX 题解 首先考虑没有+++操作时怎么做,没有+++操作后每个位相对独立,可以设prei,jp ...

最新文章

  1. spring配置文件中分别使用多个properties文件
  2. pmp考试中容易混淆的22组概念
  3. linux qt5.9 下载,在Ubuntu17.04上安装QT5.9.0(下载、安装、问题解决)
  4. Linq 下的 Take() 方法内部机制是怎样的?
  5. django-模板加载顺序-随堂
  6. oracle中schema是什么,ORACLE中的两个概念:user和schema的区别和联系
  7. 沈大海38节jquery强化教程2016视频下载
  8. C++:堆排序算法详解
  9. linux下安装nginx
  10. 多Excel文件内容查询工具
  11. liu系统的混沌特性及其matlab仿真,Liu系统的混沌特性及其Matlab仿真
  12. CRAFT字符检测算法和SynthText合成文本数据集
  13. JavaScript实现节点的增加修改删除查找
  14. 违背妇女意志_2018年国际妇女节:在技术中庆祝妇女
  15. foobar的cue生成插件
  16. Photoshop支持ICO图片格式
  17. 在浏览器中输入网址到网页展现全部过程
  18. UVA10382 - Watering Grass 题解
  19. 通过 Hostapd 进行 WIFI 热点共享上网
  20. java remote desktop_Chrome Remote Desktop:让你在任意设备上远程连接Windows桌面

热门文章

  1. Linux怎么添加交换空间,如何在Ubuntu上增加swap交换空间
  2. python不同时间周期k线_请问期货不同时间级别的k线呈现相反形态怎么判断买卖点?...
  3. python 连接oracle学习
  4. html框架里面怎么填写内容_还不会Python高级框架?进来,速学
  5. 2008版计算机基础,计算机应用基础2008版各章课后习题解析
  6. 哗啦啦用Java_哗啦啦
  7. JAVA写的文件分割与文件合并程序
  8. 集合 Collection 与迭代器 Iterator
  9. Java项目课程04:需求分析
  10. Maven项目设置仓库下载位置