【BZOJ3064】CPU监控(线段树)

题面

BZOJ

洛谷

题解

神仙\(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监控(线段树)的更多相关文章

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

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

  2. CPU监控 线段树裸题

    LINK:bzoj3064 此题甚好码了20min停下来思考的时候才发现不对的地方有点坑... 还真不好写来着 可这的确是线段树的裸题...我觉得我写应该没有什么大问题 不过思路非常的紊乱 如果是自己 ...

  3. BZOJ.3064.CPU监控(线段树 历史最值)

    题目链接 \(Description\) 有一个长为n的序列Ai,要求支持查询[l,r]的最值.历史最值,区间加/重设 \(Solution\) 线段树,每个点再维护一个历史(从0到现在)最大值.历史 ...

  4. BZOJ3064 Tyvj 1518 CPU监控 线段树

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

  5. bzoj3064 CPU监控

    今天终于写了一道正常的题 思路是这样的: 1.普通线段树add,set不变,并改为下放标记版本 2.past_addv 记录一个区间内可能的addv值的最大值 3.past_setv 记录一个区间被s ...

  6. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

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

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

  8. bzoj3064/洛谷P4314 CPU监控【线段树】

    好,长草博客被催更了[?] 我感觉这题完全可以当作线段树3 线段树2考加法和乘法标记的下放顺序,这道题更丧心病狂[?] 很多人可能跟我一样,刚看到这道题秒出思路:打一个当前最大值一个历史最大值不就完事 ...

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

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

随机推荐

  1. halcon 手眼标定的坐标转换原理讲解

    原文链接:https://blog.csdn.net/opencv_learner/article/details/82113323 一直以来,对于手眼标定所涉及到的坐标系及坐标系之间的转换关系都没能 ...

  2. C#_Switch语句的内部实现

    Switch的C#内部实现 https://www.cnblogs.com/Interkey/p/3730432.html 在IL汇编语言中的Switch指令 -- 按照标号来进行跳转(和goto语句 ...

  3. 4. 为HelloWorld添加日志

    回顾 通过上篇内容,我们已经使用flask编写了我们的第一个接口或者说是html页面.我们可以看到,使用flask来编写接口/页面是十分简单的.那么接下来,我们丰富一下上面的例子. 需求 现在的需求来 ...

  4. ReLU——Deep Sparse Rectifier Neural Networks

    1. 摘要 ReLU 相比 Tanh 能产生相同或者更好的性能,而且能产生真零的稀疏表示,非常适合自然就稀疏的数据. 采用 ReLU 后,在大量的有标签数据下,有没有无监督预训练模型取得的最好效果是一 ...

  5. React Native (0.57)开发环境搭建(注意:Node不要随便更新到最新版,更新完后莫名其妙的问题一大堆)

    搭建开发环境 一.安装依赖 必须安装的依赖有:Node.Watchman 和 React Native 命令行工具以及 Xcode. 1.首先安装 Homebrew 2.安装 Node, Watchm ...

  6. No.100_第一次团队会议

    任务的确立 这次会议,我们的主要目标是确定任务: 我们的任务有以下几个选择: 学霸网站,这个项目拥有以前的前端代码,我们再使用Django后端服务.上手难度较低,环境较好. 多平台时间管理软件. 安卓 ...

  7. Alpha阶段展示报告

    一.团队成员简介与个人博客地址 江昊,项目经理 http://www.cnblogs.com/haoj/ 王开,后端开发 http://www.cnblogs.com/wk1216123/ 王春阳,后 ...

  8. WebGL学习笔记三

    在上一章中主要说明了通过矩阵来实现平面图形的平移.旋转.缩放,到最后完全可以用4*4矩阵实现所有的动作,在本章就是第四章主要是对矩阵进行了封装,其WebGL的流程和上一章大部分大部分相同,定义可以在w ...

  9. Leetcode题库——17.电话号码的字母组合

    @author: ZZQ @software: PyCharm @file: letterCombinations.py @time: 2018/10/18 18:33 要求:给定一个仅包含数字 2- ...

  10. mongo导入导出命令

    1.导出工具:mongoexport     1.概念:         mongoDB中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指 ...