论文题。

考虑到这题的维护和区间操作是反向的,也就是说无法像V那题快速的合并标记。

我们知道,一个区间的最小值和其他值是可以分开来维护的,因为如果一个区间被整体覆盖,那么最小值始终是最小值。

对于被覆盖一半的区间,讨论一下即可。

对于每个最小值和次小值记录前缀最小值,当前/历史最小值,当到达合法区间的时候:

如果区间最小值>x,直接退出。

如果minv[o]<x<semn[o],那么更新当前的次小值

反之继续向下。

#include<bits/stdc++.h>
const int inf=2e9+;
const int N=;
using namespace std;
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int n,m;
struct Segment_Tree_Beats{
#define lson (o<<1)
#define rson (o<<1|1)
int his[N<<],pra[N<<],prb[N<<],a[N<<],b[N<<],minv[N<<],semn[N<<];
inline void pushup(int o){
if(minv[lson]==minv[rson])minv[o]=minv[lson],semn[o]=min(semn[lson],semn[rson]);
else if(minv[lson]<minv[rson]){minv[o]=minv[lson];semn[o]=min(semn[lson],minv[rson]);}
else{minv[o]=minv[rson];semn[o]=min(semn[rson],minv[lson]);}
his[o]=min(his[lson],his[rson]);
}
inline void puttag(int o,int v){
his[o]=min(his[o],minv[o]+v);
a[o]+=v;b[o]+=v;minv[o]+=v;semn[o]+=v;semn[o]=min(semn[o],inf);
pra[o]=min(pra[o],a[o]);
prb[o]=min(prb[o],b[o]);
}
inline void plus(int o,int ax,int pa,int bx,int pb){
his[o]=min(his[o],minv[o]+pa);
pra[o]=min(pra[o],pa+a[o]);
prb[o]=min(prb[o],pb+b[o]);
a[o]+=ax;b[o]+=bx;minv[o]+=ax;semn[o]+=bx;semn[o]=min(semn[o],inf);
}
inline void pushdown(int o){
int mmmm=min(minv[lson],minv[rson]);
if(minv[lson]==mmmm)plus(lson,a[o],pra[o],b[o],prb[o]);else plus(lson,b[o],prb[o],b[o],prb[o]);
if(minv[rson]==mmmm)plus(rson,a[o],pra[o],b[o],prb[o]);else plus(rson,b[o],prb[o],b[o],prb[o]);
a[o]=b[o]=pra[o]=prb[o]=;
}
inline void build(int o,int l,int r){
if(l==r){
minv[o]=read();his[o]=minv[o];semn[o]=inf;
return;
}
int mid=(l+r)>>;
build(lson,l,mid);build(rson,mid+,r);
pushup(o);
}
inline void optadd(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){puttag(o,v);return;}
int mid=(l+r)>>;pushdown(o);
if(ql<=mid)optadd(lson,l,mid,ql,qr,v);
if(qr>mid)optadd(rson,mid+,r,ql,qr,v);
pushup(o);
}
inline void dfs(int o,int l,int r,int v){
if(minv[o]>=v)return;
if(semn[o]>v){
v-=minv[o];his[o]=min(his[o],minv[o]+v);
pra[o]=min(pra[o],a[o]+v);
a[o]+=v;minv[o]+=v;return;
}
int mid=(l+r)>>;pushdown(o);
dfs(lson,l,mid,v);dfs(rson,mid+,r,v);
pushup(o);
}
inline void change(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){dfs(o,l,r,v);return;}
int mid=(l+r)>>;pushdown(o);
if(ql<=mid)change(lson,l,mid,ql,qr,v);
if(qr>mid)change(rson,mid+,r,ql,qr,v);
pushup(o);
}
inline int querynow(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return minv[o];
int mid=(l+r)>>,ans=inf;pushdown(o);
if(ql<=mid)ans=min(ans,querynow(lson,l,mid,ql,qr));
if(qr>mid)ans=min(ans,querynow(rson,mid+,r,ql,qr));
return ans;
}
inline int queryhis(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return his[o];
int mid=(l+r)>>,ans=inf;pushdown(o);
if(ql<=mid)ans=min(ans,queryhis(lson,l,mid,ql,qr));
if(qr>mid)ans=min(ans,queryhis(rson,mid+,r,ql,qr));
return ans;
}
}T;
int main(){
n=read();m=read();
T.build(,,n);
while(m--){
int opt=read(),l=read(),r=read();
if(opt==){int x=read();T.optadd(,,n,l,r,x);}
if(opt==){int x=read();T.change(,,n,l,r,x);}
if(opt==)printf("%d\n",T.querynow(,,n,l,r));
if(opt==)printf("%d\n",T.queryhis(,,n,l,r));
}
}

【UOJ#169】元旦老人与数列的更多相关文章

  1. 2018.07.28 uoj#169. 【UR #11】元旦老人与数列(线段树)

    传送门 线段树好题. 维护区间加,区间取最大值,维护区间最小值,历史区间最小值. 同样先考虑不用维护历史区间最小值的情况,这个可以参考这道题的解法,维护区间最小和次小值可以解决前两个操作,然后使用历史 ...

  2. uoj169:元旦老人与数列

    题意:http://uoj.ac/problem/169 sol  :线段树..........蜜汁TLE了一个点,不管了..... 代码抄snowMyDream的,orz........... 线段 ...

  3. 网路流 uoj 168 元旦老人与丛林

    http://uoj.ac/problem/168 没想到是网络流 官方题解地址 http://jiry-2.blog.uoj.ac/blog/1115 subtask2告诉我们度数为012的点对答案 ...

  4. UOJ169. 【UR #11】元旦老人与数列

    传送门 考虑用 \(segment~tree~beats\) 那一套理论,维护区间最小值 \(mn\) 和严格次小值 \(se\) 那么可以直接 \(mlog^2n\) 维护前三个操作 考虑维护历史最 ...

  5. [UOJ #167]【UR #11】元旦老人与汉诺塔

    题目大意:给你一个有$n$个盘子的汉诺塔状态$S$,问有多少种不同的操作方法,使得可以在$m$步以内到达状态$T$.$n,m\leqslant100$ 题解:首先可以知道的是,一个状态最多可以转移到其 ...

  6. UOJ 52 元旦激光炮

    http://uoj.ac/problem/52 题意:每次可以得到3个序列中 思路:每次分别取出三个序列的K/3长度的位置,取最小的那个,然后每次减掉它,总复杂度是Nlog3N #include & ...

  7. UR11 A.元旦老人与汉诺塔

    题目:http://uoj.ac/contest/23/problem/167 如果我们拿个map来存状态的话.设当前状态是v,下一个状态是s.有f[i+1][s]+=f[i][v]. 初始f[0][ ...

  8. uoj167 元旦老人与汉诺塔(记忆化搜索)

    QwQ太懒了,题目直接复制uoj的了 QwQ这个题可以说是十分玄学的一道题了 首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动 不多解释了,不过实现起来还是有一点点难度的 直接 ...

  9. 2018.07.29~30 uoj#170. Picks loves segment tree VIII(线段树)

    传送门 线段树好题. 维护区间取两种最值,区间加,求区间两种历史最值,区间最小值. 自己的写法调了一个晚上+一个上午+一个下午+一个晚上并没有调出来,90" role="prese ...

随机推荐

  1. XML-RPC协议学习

    XML-RPC调用包括2部分:客户端client(调用线程).服务器端server(被调用的线程).服务端是通过特定的URL获得的,调用过程如下: 1.客户端程序使用XML-RPC客户端发出作业请求, ...

  2. LOJ2350:[JOI2017/2018决赛]月票购买——题解

    https://loj.ac/problem/2350 比较简单的题,为什么我实现得这么sb? 第一个包其实已经给了提示(第一个包的解法就是在S->T所有最短路径上的所有点到V的最短路的最小值. ...

  3. BZOJ2597 [Wc2007]剪刀石头布 【费用流】

    题目链接 BZOJ2597 题解 orz思维差 既然是一张竞赛图,我们选出任意三个点都可能成环 总方案数为 \[{n \choose 3}\] 如果三个点不成环,会发现它们的度数是确定的,入度分别为\ ...

  4. ES6装饰器Decorator基本用法

    1. 基本形式 @decorator class A {} // 等同于 class A {} A = decorator(A); 装饰器在javascript中仅仅可以修饰类和属性,不能修饰函数.装 ...

  5. Linux之根文件系统介绍与分析20160611

    说一下LINUX根文件系统的介绍与分析: 1.内核启动应用程序,首先要识别出应用程序,这时就需要文件系统来帮助内核找到对应的应用程序: 2.第一个启动的应用程序就是sbin目录下的init程序,也就是 ...

  6. SpringMVC源码解析-HTTP请求处理和分发

    1.HandlerMapping的配置和设计 在初始化完成时,所有的handlerMapping都已经被加载,handlerMapping存储着HTTP请求对应的映射数据,每一个handlerMapp ...

  7. selenium - webdriver - ActionChains类(鼠标操作)

    ActionChains 类提供了鼠标操作的常用方法: perform(): 执行所有 ActionChains 中存储的行为: context_click(): 右击: double_click() ...

  8. hadoop设置公平队列

    http://hadoop.apache.org/docs/r1.2.1/fair_scheduler.html fair-scheduler.xml文档 <?xml version=" ...

  9. Leetcode 002. 两数相加

    1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  10. 手脱ASProtect v1.23 RC1(有Stolen Code)之以壳解壳

    1.载入PEID ASProtect v1.23 RC1 2.载入OD,不勾选内存访问异常,其他异常全部勾选 > 01C06D00 push SoWorker.006DC001 ; //入口点 ...