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

题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=3064

我直接用论文写法写的……论文题解如下:

刚接触这一类问题时,这个例题的难度可能较高,所以我们先忽略区间赋值操作。

考虑使用传统的懒标记来解决,首先如果只是询问区间最大值,只面要使用区间加减这一个懒标记(用\(add\)表示)就能解决。

现在考虑询问区间历史最大值的最大值。我们定义一种新的懒标记:历史最大的加减标记(用\(hisadd\)表示)。这个标记的定义是:从上一次把这个节点的标记下传的时刻到当前时刻这一时间段中,这个节点中的\(add\)标记值到达过的最大值。

现在考虑把第\(fa\)个节点的标记下传到它的儿子\(p\),不难发现标记是可以合并的:

\(hisadd_p=max(hisadd_p,add_p+hisadd_{fa}),add_p+=add_{fa}\) 。

至于区间历史最大值信息的更新也与标记的合并类似,只面要将当前的区间最大值加上\(hisadd\)然后与原来的历史最大值进行比较即可。

现在回到原题,我们观察在修改操作过程中,被影响到的节点的变化:如果一个节点没有发生标记下传,那么最开始它一直被区间加减操作所影响,这时我们可以用上面描述的\(hisadd\)标记来记录,直到某一时刻,这个节点被区间覆盖标记影响,那么这时这个节点中的所有数都变得完全相同,再之后的所有区间加减修改,对这个节点来说,与区间覆盖操作并没有不同。

因此每一个节点受到的标记可以分成两个部分:第一个部分是区间加减,第二个部分是区间覆盖。因此我们可以用 \((hisadd,hiscov)\)来表示历史最值标记,它的定义是当前区间在第一阶段时最大的加减标记是\(hisadd\),在第二个阶段时最大的覆盖标记是\(hiscov\)。显然这个标记是可以进行合并与更新的。

到此我们就使用最传统的懒标记方法解决了这个问题。

时间复杂度:\(O((n+m)logn)\)

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

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std; const int maxn=1e5+5; int n,m;
char s[20];
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 tree_node {
bool bo1,bo2;
int hismx,mx,hiscov,cov,hisadd,add;
}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) {
if(l==r) {
tree[p].mx=tree[p].hismx=a[l];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
} void add_tag(int p,int v) {
if(tree[p].bo2) {
tree[p].cov+=v;
tree[p].hiscov=max(tree[p].hiscov,tree[p].cov);
}
else {
tree[p].add+=v;
if(!tree[p].bo1)tree[p].hisadd=v,tree[p].bo1=1;
else tree[p].hisadd=max(tree[p].hisadd,tree[p].add);
}
tree[p].mx+=v;
tree[p].hismx=max(tree[p].hismx,tree[p].mx);
} void cov_tag(int p,int v) {
tree[p].cov=tree[p].mx=v;
tree[p].hismx=max(tree[p].hismx,v);
if(!tree[p].bo2)tree[p].hiscov=v,tree[p].bo2=1;
else tree[p].hiscov=max(tree[p].hiscov,v);
} void solve1(int p,int v,int hisv) {
if(tree[p].bo2) {
tree[p].hiscov=max(tree[p].hiscov,tree[p].cov+hisv);
tree[p].cov+=v;
tree[p].hismx=max(tree[p].hismx,tree[p].hiscov);
}
else {
if(!tree[p].bo1)tree[p].bo1=1,tree[p].hisadd=hisv;
else tree[p].hisadd=max(tree[p].hisadd,tree[p].add+hisv);
tree[p].add+=v;
tree[p].hismx=max(tree[p].hismx,tree[p].mx+hisv);
}
tree[p].mx+=v;
} void solve2(int p,int v,int hisv) {
if(!tree[p].bo2)tree[p].hiscov=hisv,tree[p].bo2=1;
else tree[p].hiscov=max(tree[p].hiscov,hisv);
tree[p].mx=tree[p].cov=v;
tree[p].hismx=max(tree[p].hismx,tree[p].hiscov);
} void push_down(int p) {
if(tree[p].bo1) {
solve1(p<<1,tree[p].add,tree[p].hisadd);
solve1(p<<1|1,tree[p].add,tree[p].hisadd);
tree[p].bo1=0,tree[p].add=0;
}
if(tree[p].bo2) {
solve2(p<<1,tree[p].cov,tree[p].hiscov);
solve2(p<<1|1,tree[p].cov,tree[p].hiscov);
tree[p].bo2=0;
}
} void plus(int p,int l,int r,int L,int R,int v) {
if(L<=l&&r<=R) {add_tag(p,v);return;}
int mid=(l+r)>>1;push_down(p);
if(L<=mid)plus(p<<1,l,mid,L,R,v);
if(R>mid)plus(p<<1|1,mid+1,r,L,R,v);
update(p);
} void cover(int p,int l,int r,int L,int R,int v) {
if(L<=l&&r<=R) {cov_tag(p,v);return;}
int mid=(l+r)>>1;push_down(p);
if(L<=mid)cover(p<<1,l,mid,L,R,v);
if(R>mid)cover(p<<1|1,mid+1,r,L,R,v);
update(p);
} int queryMax(int p,int l,int r,int L,int R,int opt) {
if(L<=l&&r<=R) {
if(opt)return tree[p].mx;
return tree[p].hismx;
}
int mid=(l+r)>>1,res=-2e9;push_down(p);
if(L<=mid)res=queryMax(p<<1,l,mid,L,R,opt);
if(R>mid)res=max(res,queryMax(p<<1|1,mid+1,r,L,R,opt));
return res;
}
}T; int main() {
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
T.build(1,1,n);m=read();
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
int l=read(),r=read(),v=(s[1]!='Q'&&s[1]!='A'?read():0);
if(s[1]=='P')T.plus(1,1,n,l,r,v);
if(s[1]=='C')T.cover(1,1,n,l,r,v);
if(s[1]=='Q')printf("%d\n",T.queryMax(1,1,n,l,r,1));
if(s[1]=='A')printf("%d\n",T.queryMax(1,1,n,l,r,0));
}
return 0;
}

BZOJ3064:CPU监控的更多相关文章

  1. bzoj3064 CPU监控

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

  2. 【BZOJ3064】CPU监控(线段树)

    [BZOJ3064]CPU监控(线段树) 题面 BZOJ 洛谷 题解 神仙\(zsy\)出在了\(noip\)模拟的题目.(然而\(zsy\)出的还是这题的升级版) 首先明确一点,这题是一个吉司机线段 ...

  3. [BZOJ3064][Tyvj1518] CPU监控

    题目:[BZOJ3064][Tyvj1518] CPU监控 思路: 线段树专题讲的.以下为讲课时的课件: 给出序列,要求查询一些区间的最大值.历史最大值,支持区间加.区间修改.序列长度和操作数< ...

  4. C#实现对远程服务器的内存和CPU监控

    C#实现对远程服务器的内存和CPU监控小记 1.  主要使用到的组件有System.Management.dll 2.  主要类为 :ManagementScope 连接远程服务器示例代码: priv ...

  5. Linux CPU监控指标

    Linux CPU监控指标 Linux提供了非常丰富的命令可以进行CPU相关数据进行监控,例如:top.vmstat等命令.top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执 ...

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

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

  7. CPU监控 解题报告

    CPU监控 这种题就需要小黄鸭调试法,不行就重构,动态gdb可能会死人,一堆tag的... 维护历史最值的一个核心是历史最值tag,它的意义是从上一次这个点下放tag之后到当前时刻的这个点的tag达到 ...

  8. BZOJ 3064 CPU监控

    题目链接:CPU监控 学习一番线段树的历史标记- 这道题就是区间加法,区间赋值,要询问区间最大值 和 区间历史最大值的最大值. 然后这种题就是在现有标记的基础上多弄一套标记,维护这个点出现过的最大的标 ...

  9. 安卓app测试之cpu监控

    安卓app测试之cpu监控,如何获取监控的cpu数据呢? 一.通过Dumpsys 来取值 1.adb shell dumpsys cpuinfo 二.top 1.top -d 1|grep packa ...

  10. 轻量级监控平台之cpu监控

    轻量级监控平台之cpu监控脚本 #!/bin/bash #进程监控脚本 #功能需求: 上报机器的硬件层面-cpu负载数据 . /etc/profile . ~/.bash_profile pushur ...

随机推荐

  1. 成功扩展live555支持ipv6,同时支持RTSPServer & RTSPClient

    live555对ipv6的扩展 从live555的官网看live555的发展历史,实在是历史悠久,保守估计已经发展了至少16年以上了,同时,这也导致了live555在很多架构和考虑上面不能满足现代化的 ...

  2. js跨浏览器复制: ZeroClipboard

    实例结构: demo.html <script type="text/javascript" src='http://code.jquery.com/jquery.js'&g ...

  3. php自定义函数: 加密下载地址

    function getdownurl($downurl, $extime = "3600", $serverid = 1) { if (empty($downurl)) { re ...

  4. 洛谷 P3629 [APIO2010]巡逻

    题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...

  5. centos7 mysql允许远程连接设置

    Mysql为了安全性,在默认情况下用户只允许在本地登录,可是在有此情况下,还是需要使用用户进行远程连接,因此为了使其可以远程需要进行如下操作: 一.允许root用户在任何地方进行远程登录,并具有所有库 ...

  6. full_case parallel_case学习心得

    一般情况下,DC把case语句综合成选择器电路,但也可能把case语句综合成优先权译码电路.有时,优先权译码电路是不必要的,这是可以使用“// synopsys parallel_case”引导语句强 ...

  7. python基础1 ---python简介

    python基础 一.python前言 1.什么是编程语言 编程语言是程序员与计算机之间沟通的介质. 2.编程语言的分类 机器语言:机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集 ...

  8. 图片加载控件glide

    基本用法 //(1)加载网络图片 tvGlide1.setText("(1)加载网络图片"); Glide.with(this).load("http://img1.im ...

  9. Yii2 提供可以用属性的方式去获取类的一个方法

    刚开始用 Yii 的小朋友可能对下面的写法非常疑惑: public function actionIndex() { $user = User::find()->where(['name'=&g ...

  10. P2455 [SDOI2006]线性方程组

    P2455 [SDOI2006]线性方程组 真\(\cdot\)高斯消元模板题 由于各种hack数据被造出来~码量突增~,其实也就多了二三十行 将每行系数消到最多有一个非0数 特殊情况: 在过程同时 ...