【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. Tomcat性能优化方案

    1. 提高JVM栈内存Increase JVM heap memory 你使用过tomcat的话,简单的说就是"内存溢出". 通常情况下,这种问题出现在实际的生产环境中.产生这种问 ...

  2. Docker Manager for Docker Swarm deploy

    一.Swarm概述 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Doc ...

  3. 小冷-wireshark的标志位的值是啥

    小冷系列之 wireshark的标志位的值是啥,在用wireshark抓包时,发现Flags = 0x002(SYN),很好奇0x002是什么意思. 好不好先上图: 上图是一个三次握手第一次的标志位, ...

  4. maven项目的标准目录结构

    maven项目的标准目录结构如下:

  5. golang -- 字符串就地取反

    字符串 定义 在golang中字符串是一种不可变的字节序列,它可以包含任意的数据,包括0值字节,但主要是人类可以阅读的文本.golang中默认字符串被解读为utf-8编码的Unicode码点(文字符号 ...

  6. 打包应用和构建Docker镜像(docker在windows上)

    在构建Docker时编译应用 一般有两种方法在构建镜像时进行打包应用.第一种方法就是使用基本的镜像,该镜像包括应用平台和构建工具,因此在Dockerfile中,复制源代码到镜像中并在构建镜像时编译ap ...

  7. PPIO去中心化存储的了解和记录

    目录 介绍 FileCoin P2P技术给去中心化云存储的好处 剩余资源的再次使用 市场竞争会激发民间的智慧 PPIO的2种冗余模式 全副本模式 纠删副本模式 为什么PPIO要设计支付代理节点? 一些 ...

  8. 1、Ansible安装配置

    ansible介绍: Ansible是一款基于Python开发的自动化运维工具,主要是实现批量系统配置.批量程序部署.批量运行命令.批量执行任务等等诸多功能.Ansible是一款灵活的开源工具,能够很 ...

  9. Hadoop Streaming框架使用(二)

    上一篇文章介绍了Streaming的各种参数,本文具体介绍使用方法. 提交hadoop任务示例: $HADOOP_HOME/bin/hadoop streaming \ -input /user/te ...

  10. hive的udf创建永久函数

    上传jar包到hdfs目录中, hdfs dfs -put /home/user/hive-functions.jar /user/hive/jars/hive-functions.jar   cre ...