【BZOJ3064】CPU监控(线段树)
【BZOJ3064】CPU监控(线段树)
题面
题解
神仙\(zsy\)出在了\(noip\)模拟的题目。(然而\(zsy\)出的还是这题的升级版)
首先明确一点,这题是一个吉司机线段树。
如果只有区间加法,区间赋值,区间最大值,那么这题很简单。
但是加上了一个区间历史最值,这就很烦了。
于是我们就有了一个神仙做法,
定义一个表示\((a,b)\)表示区间内所有数先\(+a\)再和\(b\)取\(max\),即\(x=max(x+a,b)\)
那么这样一来,区间加法转化成\((a,-\infty)\),区间赋值变成了\((-\infty,b)\)
考虑如何合并标记,现在有两个标记\((a,b),(x,y)\),将后者合并到前者上去。
那么可以将标记转化成\((a+x,max(b+x,y))\),原因就是注意一下\(max\)和加法的先后顺序。
对于两个标记如何合并\(max\),是\((max(a,x),max(b,y))\)。原因就是我们可以把这个标记看做是一个分段函数,那么这个合并就比较显然了。
回到题目。
这题到底在干什么呢?
首先对于维护当前值,这个东西是非常显然的。
考虑如何维护一个历史最值,我们对于每个点额外维护一个历史最值的标记,每次覆盖的时候不会覆盖掉历史最值的标记,只会用\(max\)操作更新历史最值标记。
这样子似乎就可以做了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 100100
#define lson (now<<1)
#define rson (now<<1|1)
#define inf 1050000000
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Data
{
int a,b;
void clear(){a=0;b=-inf;}
int calc(int x){return max(a+x,b);}
}mxt[MAX<<2],tag[MAX<<2];
int mx[MAX<<2],nw[MAX<<2];
Data max(Data a,Data b){return (Data){max(a.a,b.a),max(a.b,b.b)};}
Data operator+(Data a,Data b){return (Data){max(-inf,a.a+b.a),max(a.b+b.a,b.b)};}
void pushup(int now)
{
nw[now]=max(nw[lson],nw[rson]);
mx[now]=max(mx[lson],mx[rson]);
}
void puttag(int now,Data a,Data b)
{
mxt[now]=max(mxt[now],tag[now]+b);
tag[now]=tag[now]+a;
mx[now]=max(mx[now],b.calc(nw[now]));
nw[now]=a.calc(nw[now]);
}
void pushdown(int now)
{
puttag(lson,tag[now],mxt[now]);
puttag(rson,tag[now],mxt[now]);
mxt[now].clear();tag[now].clear();
}
void Build(int now,int l,int r)
{
tag[now].clear();mxt[now].clear();
if(l==r){nw[now]=mx[now]=read();return;}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
pushup(now);
}
void Modify(int now,int l,int r,int L,int R,Data a)
{
if(L<=l&&r<=R){puttag(now,a,a);return;}
int mid=(l+r)>>1;pushdown(now);
if(L<=mid)Modify(lson,l,mid,L,R,a);
if(R>mid)Modify(rson,mid+1,r,L,R,a);
pushup(now);
}
int Query(int now,int l,int r,int L,int R,int opt)
{
if(L==l&&r==R)return opt?mx[now]:nw[now];
int mid=(l+r)>>1;pushdown(now);
if(R<=mid)return Query(lson,l,mid,L,R,opt);
if(L>mid)return Query(rson,mid+1,r,L,R,opt);
return max(Query(lson,l,mid,L,mid,opt),Query(rson,mid+1,r,mid+1,R,opt));
}
int n,m;
char ch[20];
int main()
{
n=read();Build(1,1,n);m=read();
while(m--)
{
scanf("%s",ch);
int l=read(),r=read();Data a=(Data){-inf,-inf};
if(ch[0]=='Q')printf("%d\n",Query(1,1,n,l,r,0));
else if(ch[0]=='A')printf("%d\n",Query(1,1,n,l,r,1));
else if(ch[0]=='P')a.a=read(),Modify(1,1,n,l,r,a);
else a.b=read(),Modify(1,1,n,l,r,a);
}
return 0;
}
【BZOJ3064】CPU监控(线段树)的更多相关文章
- 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值
题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...
- CPU监控 线段树裸题
LINK:bzoj3064 此题甚好码了20min停下来思考的时候才发现不对的地方有点坑... 还真不好写来着 可这的确是线段树的裸题...我觉得我写应该没有什么大问题 不过思路非常的紊乱 如果是自己 ...
- BZOJ.3064.CPU监控(线段树 历史最值)
题目链接 \(Description\) 有一个长为n的序列Ai,要求支持查询[l,r]的最值.历史最值,区间加/重设 \(Solution\) 线段树,每个点再维护一个历史(从0到现在)最大值.历史 ...
- BZOJ3064 Tyvj 1518 CPU监控 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3064 题意概括 一个序列,要你支持以下操作: 1. 区间询问最大值 2. 区间询问历史最大值 3. ...
- bzoj3064 CPU监控
今天终于写了一道正常的题 思路是这样的: 1.普通线段树add,set不变,并改为下放标记版本 2.past_addv 记录一个区间内可能的addv值的最大值 3.past_setv 记录一个区间被s ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 2018.07.27 bzoj3064: Tyvj 1518 CPU监控(线段树)
传送门 线段树好题. 维护区间加,区间覆盖,区间最大,区间历史最大. 这个东西在国家集训队2016论文集之<区间最值操作与历史最值问题--杭州学军中学 吉如一>中讲的已经很详细了. 简单来 ...
- bzoj3064/洛谷P4314 CPU监控【线段树】
好,长草博客被催更了[?] 我感觉这题完全可以当作线段树3 线段树2考加法和乘法标记的下放顺序,这道题更丧心病狂[?] 很多人可能跟我一样,刚看到这道题秒出思路:打一个当前最大值一个历史最大值不就完事 ...
- Tyvj 1518 CPU监控(线段树)
题目描述: Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用 ...
随机推荐
- Unity新版本VR以及SteamVR基础
一.Unity2018新版本VR Unity 简单VRDemo搭建 Unity环境搭建: PlayerSetting设置如下: 启动虚拟现实驱动,sdk选择OpenVR.HTC Vive只支持Ope ...
- BAT面试必备——Java 集合类
本文首发于我的个人博客:尾尾部落 1. Iterator接口 Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法.它的一个子接 ...
- passwd命令详解
基础命令学习目录首页 passwd命令用于设置用户的认证信息,包括用户密码.密码过期时间等.系统管理者则能用它管理系统用户的密码.只有管理者可以指定用户名称,一般用户只能变更自己的密码. 语法 pas ...
- 通过exp命令对Oracle数据库进行备份操作(提供两种情况的备份:备份本地,备份远程的数据库)
exp 用户名/密码@数据库所在ip地址:数据库端口号/数据库的service-name file=存储到的位置 这个是能成功的 http://www.2cto.com/database/201402 ...
- 第十三次作业psp
psp 进度条 代码累积折线图 博文累积折线图 psp饼状图
- 第二阶段Sprint3
昨天:查看资料,开始视频录制部分的代码实现 今天:事实现保存到指定路径,并能够选择播放 遇到的问题:自动生成文件名,是否需要自己命名?怎么实现?
- "私人助手"NABCD分析
---恢复内容开始--- 团队开发项目“私人助手”需求分析NABCD模型: (1)N(Need需求):“私人助手”解决了几类人遇到非常多的事情,非常繁琐,“私人助手”为用户解决这个问题,让用户的工作更 ...
- 剑指offer:矩形覆盖
题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 解题思路: 和跳台阶那道题差不多.分别以矩形的两条边长做拓 ...
- UDP与TCP笔记
1.UDP UDP协议在工作时是建立在IP协议之上的,UDP从进程的缓冲区接收进程每一次产生的输出,对每次输出都生成一个UDP数据报,然后把生成的UDP数据报直接封装在IP数据报中进行传输,因此在传输 ...
- iOS UIView性能最优的设计圆角并且绘制边框颜色
//以给cell切圆角为例- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollection ...