题目大意:

给定一个区间及其各个元素的初值,要求支持如下操作:

1.区间加

2.区间赋值

3.查询区间最大值

4.查询区间历史最大值

分析:

容易想到线段树,但是细思恶极(仔细想想恶心到了极点)的是,最后查询区间历史最大值的操作。

如果只记录区间历史最大值显然不能下放,如果单纯更新区间加,区间赋值最大值,可能会出现历史最大值更新不及时的情况。如先赋值很大值,未来得及下放,又赋值很小,导致子区间历史最大值不能更新。又如如果区间加只取最大值,可能会只取最大值,导致实际上忽视了一些使区间加变小的操作。

。。。。(此处省略若千字)

所以我们记录如下几点:

1.mx(x)当前区间最大值

2.hx(x)历史区间最大值

3.ad(x)当前区间加

4.ha(x)历史最大区间加

5.ch(x)当前区间赋值

6.hc(x)历史最大区间赋值

注意 :

这里我们所谓的ha,hc是指在上一次pushdown之后,期间进行的操作中的最大值。是可以清零的,不像hx。

初值:ha=ad=0,ch=hc=-inf。

因为每次都先进行pushdown,所以ha、hc直接随着ad、ch更新。

注意的是pushdown中的许多讨论,自己分析清楚。

其实每次都pushdown是很慢的,会tle两个点。

然后就把区间内的l、r不记录了,竟然不开O2水过。

详见代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=+;
const ll inf=1e13;
int root,n,e;
ll a[N];
int cc;
struct node{
ll add,ch;
ll mx,hx;
ll had,hch;//一段时间内最值
#define ad(x) t[x].add
#define ch(x) t[x].ch
#define mx(x) t[x].mx
#define hx(x) t[x].hx
#define ha(x) t[x].had
#define hc(x) t[x].hch
#define l(x) t[x].l
#define r(x) t[x].r
}t[*N];
void pushup(int x)
{
int s1=x<<,s2=x<<|;
mx(x)=max(mx(s1),mx(s2));
hx(x)=max(hx(s1),hx(s2));
}
void build(int x,int L,int R)
{
if(L==R)
{
ad(x)=;ch(x)=-inf;ha(x)=;hc(x)=-inf;
mx(x)=hx(x)=a[L];
return;
}
int mid=(L+R)>>;
ad(x)=;ch(x)=-inf;ha(x)=;hc(x)=-inf;
mx(x)=hx(x)=-inf;
build(x<<,L,mid);
build(x<<|,mid+,R);
pushup(x);
}
void pushdown(int x)
{
for(int i=;i<=;i++)
{
int s=x<<|i;
hx(s)=max(hx(s),max(mx(s)+ha(x),hc(x)));
if(ch(s)!=-inf) hc(s)=max(hc(s),ch(s)+ha(x));
else ha(s)=max(ha(s),ad(s)+ha(x));
if(ad(x))
{
if(ch(s)!=-inf) ch(s)+=ad(x);
else ad(s)+=ad(x);
mx(s)+=ad(x);
}
if(ch(x)!=-inf)
{
mx(s)=ch(s)=ch(x);
ad(s)=;
}
hc(s)=max(hc(s),max(ch(s),hc(x)));
ha(s)=max(ha(s),ad(s));
}
hc(x)=-inf;
ad(x)=;ch(x)=-inf;ha(x)=;
}
void add(int x,int l,int r,int L,int R,ll c)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
ad(x)+=c;ha(x)+=c;
mx(x)+=c;hx(x)=max(mx(x),hx(x));
return;
} int mid=(l+r)>>;
if(L<=mid) add(x<<,l,mid,L,R,c);
if(R>mid) add(x<<|,mid+,r,L,R,c);
pushup(x);
}
void chan(int x,int l,int r,int L,int R,ll c)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
ch(x)=c,mx(x)=c;hc(x)=c;
hx(x)=max(hx(x),mx(x));
return;
}
int mid=(l+r)>>;
if(L<=mid) chan(x<<,l,mid,L,R,c);
if(R>mid) chan(x<<|,mid+,r,L,R,c);
pushup(x);
}
ll qx(int x,int l,int r,int L,int R)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
return mx(x);
}
int mid=(l+r)>>;
ll res=-inf;
if(L<=mid) res=max(res,qx(x<<,l,mid,L,R));
if(R>mid) res=max(res,qx(x<<|,mid+,r,L,R));
return res;
}
ll qh(int x,int l,int r,int L,int R)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
return hx(x);
}
int mid=(l+r)>>;
ll res=-inf;
if(L<=mid) res=max(res,qh(x<<,l,mid,L,R));
if(R>mid) res=max(res,qh(x<<|,mid+,r,L,R));
return res;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
root=;
build(,,n);
scanf("%d",&e);
char q;
int x,y;
ll z;
while(e)
{
cin>>q;
if(q=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",qx(root,,n,x,y));
}
else if(q=='A')
{ scanf("%d%d",&x,&y);
printf("%lld\n",qh(root,,n,x,y));
}
else if(q=='P')
{
scanf("%d%d%lld",&x,&y,&z);
add(root,,n,x,y,z);
}
else{
scanf("%d%d%lld",&x,&y,&z);
chan(root,,n,x,y,z);
}
e--;
}
return ;
}

做这个题要有勇于试错的精神,和坚持不懈的意志。

Tyvj 1518 CPU监控——极恶线段树的更多相关文章

  1. [补档][Tyvj 1518]CPU监控

    [Tyvj 1518]CPU监控 题目 Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看 ...

  2. 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值

    题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...

  3. Tyvj 1518 CPU监控(线段树)

    题目描述: Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用 ...

  4. 2018.07.27 bzoj3064: Tyvj 1518 CPU监控(线段树)

    传送门 线段树好题. 维护区间加,区间覆盖,区间最大,区间历史最大. 这个东西在国家集训队2016论文集之<区间最值操作与历史最值问题--杭州学军中学 吉如一>中讲的已经很详细了. 简单来 ...

  5. bzoj3064 Tyvj 1518 CPU监控

    Description Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做 ...

  6. bzoj 3064: Tyvj 1518 CPU监控

    Description 1.区间加 \(z\) 2.区间覆盖为 \(z\) 3.查询区间最大值 4.查询区间历史最大值 Solution 线段树维护历史最值,思想大致是维护标记出现过的最大值 考虑这种 ...

  7. BZOJ3064 Tyvj 1518 CPU监控 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3064 题意概括 一个序列,要你支持以下操作: 1. 区间询问最大值 2. 区间询问历史最大值 3. ...

  8. 3064: Tyvj 1518 CPU监控

    注意这题要维护历史最大加和历史最大覆盖 /************************************************************** Problem: 3064 Us ...

  9. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

随机推荐

  1. *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)

    最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画.之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来: 我的开发环境是在VS2017下进行 ...

  2. 从零开始搭建属于你的React/redux/webpack脚手架

    大家好,我是苏南,今天要给大家分享的是<<我的react入门到放弃之路>>,当然,也不是真的放弃啦--哈哈,这篇博客原本是从17年初写的,一直没有在csdn发布,希望今天不会太 ...

  3. java内存溢出的解决思路

    原文地址:https://www.cnblogs.com/200911/p/3965108.html 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能 ...

  4. HTTP 及相关知识

    什么是HTTP.流程? 什么是AJAX.方法.状态码?

  5. mac系统下修复第三方Python包bug

    发现问题 今天在github上fork了CI 3.x的中文手册,按照README文档一步步进行Sphinx和相关工具的安装,最终build生成html版手册.操作到第6步执行`make html`的时 ...

  6. 《Linux内核设计与实现》第五章学习笔记

    <Linux内核设计与实现>第五章学习笔记 姓名:王玮怡  学号:20135116 一.与内核通信     在Linux中,系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核 ...

  7. sring引入mybatis

    1.首先框架结构是这样的(jar包还是要导的) 2.web.xml和springMVC-servlet.xml未作任何新的配置,这里简单贴一下代码: <?xml version="1. ...

  8. 第七组团队项目——专业课程资源共享平台——需求分析&原型设计

    一.项目目标.定位需求: (1)目标:在教师.学生之间建立一个综合的.全面的.快捷的.高效的免费课程和学习资源共享.交流与推荐的开放性平台,实现多维和动态的推荐与分类检索服务. (2)定位:学生与教师 ...

  9. 最新一课 老师指点用Listview适配器

    上课前 <?xml version="1.0" encoding="utf-8"?>    <ScrollView xmlns:android ...

  10. Javascript中实现继承的方式

    js中实现继承和传统的面向对象语言中有所不同:传统的面向对象语言的继承由类来实现,而在js中,是通过构造原型来实现的,原型与如下几个术语有关: ①构造函数:在构造函数内部拥有一个prototype属性 ...