浅谈区间最值操作与历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html

题目传送门:http://uoj.ac/problem/164

论文题。论文做法如下:

首先我们定义一种标记\((a,b)\),表示给这个区间先加上\(a\)再跟\(b\)取\(max\),不难发现题目里提到的三种操作分别都可以用这样的标记来代替:

1、区间加\(v\):\((v,-inf)\)

2、区间减\(v\):\((-v,0)\)

3、区间覆盖:\((-inf,v)\)

考虑合并两个标记\((a,b),(c,d)\),那么就会变成\((a+c,max(b+c,d))\)。

现在考虑历史标记最大值,对于一个标记,我们可以将它看成是一个分段函数。第一段的函数是\(y=b\),第二段的函数是\(y=x+a\)。那么历史最大标记则可以用\((max(a,c),max(b,d))\)来表示。如下图,红色的部分就是历史标记最大值:

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll; const ll inf=1e18;
const int maxn=5e5+5; int n,m;
int a[maxn]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct segment_tree {
struct tag {
ll add,mx; void init() {
add=0,mx=-inf;
} tag() {} tag(ll _add,ll _mx) {
add=_add,mx=_mx;
} tag operator+(const tag &a)const {
return tag(max(-inf,add+a.add),max(mx+a.add,a.mx));
} tag operator*(const tag &a)const {
return tag(max(add,a.add),max(mx,a.mx));
}
}; struct tree_node {
ll hismx,mx;
tag his,now;
}tree[maxn<<2]; void update(int p) {
tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx);
tree[p].hismx=max(tree[p<<1].hismx,tree[p<<1|1].hismx);
} void build(int p,int l,int r) {
tree[p].his.init(),tree[p].now.init();
if(l==r) {tree[p].hismx=tree[p].mx=a[l];return;}
int mid=(l+r)>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
update(p);
} void make_tag(int p,tag now,tag his) {
tree[p].his=tree[p].his*(tree[p].now+his);
tree[p].now=tree[p].now+now;
ll res=max(tree[p].mx+his.add,his.mx);
tree[p].hismx=max(tree[p].hismx,res);
tree[p].mx=max(tree[p].mx+now.add,now.mx);
} void push_down(int p) {
make_tag(p<<1,tree[p].now,tree[p].his);
make_tag(p<<1|1,tree[p].now,tree[p].his);
tree[p].now.init(),tree[p].his.init();
} void change(int p,int l,int r,int L,int R,ll v,ll mx) {
if(L<=l&&r<=R) {make_tag(p,tag(v,mx),tag(v,mx));return;}
int mid=(l+r)>>1;push_down(p);
if(L<=mid)change(p<<1,l,mid,L,R,v,mx);
if(R>mid)change(p<<1|1,mid+1,r,L,R,v,mx);
update(p);
} ll query(int p,int l,int r,int pos,int opt) {
if(l==r) return opt==4?tree[p].mx:tree[p].hismx;
int mid=(l+r)>>1;push_down(p);
if(pos<=mid)return query(p<<1,l,mid,pos,opt);
else return query(p<<1|1,mid+1,r,pos,opt);
}
}T; int main() {
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
T.build(1,1,n);
for(int i=1;i<=m;i++) {
int opt=read(),l=0,r=0,v=0,pos=0;
if(opt>3)pos=read();
else l=read(),r=read(),v=read();
if(opt==1)T.change(1,1,n,l,r,v,-inf);
if(opt==2)T.change(1,1,n,l,r,-v,0);
if(opt==3)T.change(1,1,n,l,r,-inf,v);
if(opt>3)printf("%lld\n",T.query(1,1,n,pos,opt));
}
return 0;
}

UOJ#164:【清华集训2015】V的更多相关文章

  1. UOJ #164 [清华集训2015]V (线段树)

    题目链接 http://uoj.ac/problem/164 题解 神仙线段树题. 首先赋值操作可以等价于减掉正无穷再加上\(x\). 假设某个位置从前到后的操作序列是: \(x_1,x_2,..., ...

  2. 清华集训2015 V

    #164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...

  3. 【uoj#164】[清华集训2015]V 线段树维护历史最值

    题目描述 给你一个长度为 $n$ 的序列,支持五种操作: $1\ l\ r\ x$ :将 $[l,r]$ 内的数加上 $x$ :$2\ l\ r\ x$ :将 $[l,r]$ 内的数减去 $x$ ,并 ...

  4. 「清华集训2015」V

    「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...

  5. [UOJ#274][清华集训2016]温暖会指引我们前行

    [UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...

  6. UOJ #164. 【清华集训2015】V | 线段树

    题目链接 UOJ #164 题解 首先,这道题有三种询问:区间加.区间减(减完对\(0\)取\(\max\)).区间修改. 可以用一种标记来表示--标记\((a, b)\)表示把原来的值加上\(a\) ...

  7. 2018.07.28 uoj#164. 【清华集训2015】V(线段树)

    传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...

  8. UOJ #164 【清华集训2015】 V

    题目链接:V 这道题由于是单点询问,所以异常好写. 注意到每种修改操作都可以用一个标记\((a,b)\)表示.标记\((a,b)\)的意义就是\(x= \max\{x+a,b\}\) 同时这种标记也是 ...

  9. @uoj - 164@ 【清华集训2015】V

    目录 @description@ @solution@ @accepted code@ @details@ @description@ Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化 ...

随机推荐

  1. 记录-MySQL中的事件调度Event Scheduler

    下面是自己的实例 /*查询event是否开启(查询结果Off为关闭 On为开启)*/show variables like '%sche%'; /*开启/关闭命令(1开启--0关闭)*/set glo ...

  2. java Web程序使用wro4j合并、压缩js、css等静态资源

    在Web项目中,js.css合并压缩,不仅有利于减少Http请求数量.减少宽带资源占用,还能有效的管理各种js.css的引入,使整个项目更加有序.而对于访问用户来说,其更大的好处是增加了页面的打开速度 ...

  3. WCF基础之序列化

    wcf是基于消息进行通信的,这篇就是简单说下序列化引擎是如何将.net object转化为xml消息.一般情况下很少用到这些,你只需定义数据协定之类的或者指定相应的序列化引擎,然后设置相应的特性就好. ...

  4. Java基础 - 变量的定义和使用

    变量定义 public class Main { public static void main(String[] args) { // 定义byte类型的变量 byte b = 10; System ...

  5. 如何用excel urldecode解码把url编码转为汉字?

    统计分析可以反映出网站运营的情况,并根据实际作出相应的调整,是站长必需的基础技能.ytkah感觉最好用的是谷歌统计,里面有个搜索关键词及对应受访页面,这个功能对优化用处很大,但大家都知道访问不太顺畅. ...

  6. MD_STOCK_REQUIREMENTS_LIST_API 取MD04的MRP Element

    [转http://lz357502668.blog.163.com/blog/static/16496743201231941718527/]?MD_STOCK_REQUIREMENTS_LIST_A ...

  7. MySQL一些常见查询方式

    1.查询端口号命令: show global variables like 'port'; 2.查看版本号: select version(); 3.查看默认安装的MySQL的字符集 show var ...

  8. MOOC 数据结构 01-复杂度3 二分查找

    01-复杂度3 二分查找(20 分) 本题要求实现二分查找算法. 函数接口定义: Position BinarySearch( List L, ElementType X ); 其中List结构定义如 ...

  9. 隐藏c语言烦人的{ }

    .vimrc文件中添加 autocmd BufNewFile,BufRead * :syn match braces conceal "[{}]" set conceallevel ...

  10. maven导入项目时,缺少部分source folder

    今天导入公司的maven项目时,少了一些source folder,运行启动正常,但是页面打不开,找不到对应的目录文件,使用maven更新项目,重启编辑器也无效. 问题描述如图所示,缺少了图中的2个目 ...