【bzoj3064】 CPU监控

http://www.lydsy.com/JudgeOnline/problem.php?id=3064 (题目链接)

题意

  给出一个长度为$n$的数列$A$,同时定义一个辅助数组$B$,$B$开始与$A$完全相同。接下来进行$m$次操作, 有4种类型:

  1. 区间加法
  2. 区间覆盖
  3. 查询$A$的区间最值
  4. 查询$B$的区间最值

Solution

  参考吉利论文。

  最恶心的就是覆盖标记和加减标记的合并=  =,一定要想清楚所有情况。

细节

  代码略丑=  =

代码

// bzoj3938
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;

const int maxn=100010;
int n,m,a[maxn];
char ch[100];
struct node {int l,r,nadd,padd,ncov,pcov,nmx,pmx;}tr[maxn<<2];

void pushup(int k) {
	tr[k].nmx=max(tr[k<<1].nmx,tr[k<<1|1].nmx);
	tr[k].pmx=max(tr[k<<1].pmx,tr[k<<1|1].pmx);
}
void pushdown(int k) {
	for (int x,i=0;x=k<<1|i,i<2;i++) {
		tr[x].pmx=max(tr[x].pmx,max(tr[k].padd+tr[x].nmx,tr[k].pcov));
		if (tr[k].ncov==-inf) {
			tr[x].nmx+=tr[k].nadd;
			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd),tr[x].nadd+=tr[k].nadd;
			else tr[x].pcov=max(tr[x].pcov,tr[x].ncov+tr[k].padd),tr[x].ncov=tr[x].nmx;
		}
		else {
			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd);
			else tr[x].pcov=max(tr[x].pcov,tr[x].nmx+tr[k].padd);
			tr[x].nmx=tr[x].ncov=tr[k].ncov,tr[x].pcov=max(tr[x].pcov,tr[k].pcov);
		}
	}
	tr[k].ncov=tr[k].pcov=-inf;tr[k].nadd=tr[k].padd=0;
}
void build(int k,int s,int t) {
	tr[k].l=s;tr[k].r=t;
	tr[k].ncov=tr[k].pcov=-inf;
	if (s==t) {tr[k].nmx=tr[k].pmx=a[s];return;}
	int mid=(s+t)>>1;
	build(k<<1,s,mid);
	build(k<<1|1,mid+1,t);
	pushup(k);
}
int query(int k,int s,int t,int op) {
	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
	if (l==s && r==t) return op ? tr[k].pmx : tr[k].nmx;
	pushdown(k);
	if (t<=mid) return query(k<<1,s,t,op);
	else if (s>mid) return query(k<<1|1,s,t,op);
	else return max(query(k<<1,s,mid,op),query(k<<1|1,mid+1,t,op));
}
void modify(int k,int s,int t,int val,int op) {
	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
	if (l==s && r==t) {
		if (op) {
			tr[k].pmx=max(tr[k].pmx,tr[k].nmx=val);
			tr[k].pcov=max(tr[k].pcov,tr[k].ncov=val);
		}
		else {
			tr[k].pmx=max(tr[k].pmx,tr[k].nmx+=val);
			if (tr[k].ncov==-inf) tr[k].padd=max(tr[k].padd,tr[k].nadd+=val);
			else tr[k].pcov=max(tr[k].pcov,tr[k].ncov=tr[k].nmx);
		}
		return;
	}
	pushdown(k);
	if (t<=mid) modify(k<<1,s,t,val,op);
	else if (s>mid) modify(k<<1|1,s,t,val,op);
	else modify(k<<1,s,mid,val,op),modify(k<<1|1,mid+1,t,val,op);
	pushup(k);
}
int main() {
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	scanf("%d",&m);
	for (int x,y,z,i=1;i<=m;i++) {
		scanf("%s%d%d",ch,&x,&y);
		if (ch[0]==‘Q‘) printf("%d\n",query(1,x,y,0));
		if (ch[0]==‘A‘) printf("%d\n",query(1,x,y,1));
		if (ch[0]==‘P‘) scanf("%d",&z),modify(1,x,y,z,0);
		if (ch[0]==‘C‘) scanf("%d",&z),modify(1,x,y,z,1);
	}
	return 0;
}
时间: 2024-10-05 04:27:32

【bzoj3064】 CPU监控的相关文章

[bzoj3064]CPU监控

首先考虑没有区间历史最大值,用线段树维护每一个区间的一个二元组(x,y),表示区间内所有数先加上x在和y取max,然后就要支持标记的修改和合并修改:如果对(x,y)修改一个(x',y'),那么就是(x+x',max(y+x',y'))合并:如果将(x1,y1)和(x2,y2)合并,那么就是(max(x1,x2),max(y1,y2))用这个东西就可以维护区间当前最大值了,那么历史最大值也可用同样的方式,只是不能直接覆盖而是对其取max即可 1 #include<bits/stdc++.h> 2

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

C#实现对远程服务器的内存和CPU监控小记 1.  主要使用到的组件有System.Management.dll 2.  主要类为 :ManagementScope 连接远程服务器示例代码: 1 private const string PROPERTY_CAPACITY = "Capacity"; 2 private const string PROPERTY_AVAILABLE_BYTES = "AvailableBytes"; 3 private const

CPU监控 解题报告

CPU监控 这种题就需要小黄鸭调试法,不行就重构,动态gdb可能会死人,一堆tag的... 维护历史最值的一个核心是历史最值tag,它的意义是从上一次这个点下放tag之后到当前时刻的这个点的tag达到过的最大值. 我们注意到tag的作用是按找时间限制的,所以我们可以认为历史最大tag是一个前缀最大值. 有了历史最值tag,我们就可以完成pushdown的工作辣 就把历史tag放给儿子的历史tag和历史最值,这时候更新需要用儿子的当前值结合自己的历史最大进行更新. 对这个题维护一个二元组\(tag

安卓app测试之cpu监控

安卓app测试之cpu监控,如何获取监控的cpu数据呢? 一.通过Dumpsys 来取值 1.adb shell dumpsys cpuinfo 二.top 1.top -d 1|grep packageName adb shell "top -d 1|grep tv.danmaku.bili" 原文地址:https://www.cnblogs.com/wuzm/p/10969003.html

P4314 CPU监控

P4314 CPU监控 好一道神仙题 思路来源于yyb神仙 题目要求我们支持4个操作: 区间赋值 区间加 区间最大值 区间历史最大值 这第四个操作简直是BUG一样的存在 思考一下,发现难点在于维护区间历史最大值 先打完这些: #include<bits/stdc++.h> using namespace std; const int N=100005; #define INF 1050000000 struct TAG{ #define il inline int a,b; il void c

bzoj3064: Tyvj 1518 CPU监控 线段树

线段树维护两个值四个标记,注意打标记的顺序. #include<bits/stdc++.h> #define N (1<<18) #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define L l,M,P #define R M+1,r,S #define Z int l=1,int r=n,int k=1 using namespace std; int n; typedef i

【BZOJ3064】【Tyvj1518】CPU监控 裸线段树

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43271091"); } 题解:显然是裸的线段树,连区间合并都没有,更别提可持久化了... 水得一比,但是也相当恶心.. 维护一下: 目前线段 最大值.覆盖值.增加值. 历史线段 最大值.覆盖值.增加值. 然后覆盖值是赋-inf还是再加个flag记录有

BZOJ3064: Tyvj 1518 CPU监控

n<=100000的数列支持以下操作:一.区间加:二.区间赋值:三.查区间最大:四.查区间历史版本最大. 恶心死我了..可能很水,但我调了半天. 错误!调了两天. 这里有一个棘手问题:历史版本. 首先不看赋值操作.记俩标记--区间加add和区间历史加标记pre.其中后者的含义是"从上一次这个区间标记下传到现在,区间加(前者)标记的最大值".这样,比如某点i的标记下传给儿子x,标记如此叠加:$pre_x>?=pre_i+add_x$,$add_x+=add_i$,同时更新区间

cpu监控数据及cpu几核关系

1.监控CPU,主要有%processor time 和CPU队列长度(Processor __), 一般%processor time≤75%正常 Cpu队列长度 值如果一直大于 核数,说明进程一直排队,存在处理器瓶颈,引起处理器堵塞,可能会影响事务成功率等 2.查看几核方法 方法一:点击资源管理器(ctrl+alt+delete),点击性能监视器,查看CPU,个数 方法二:点击我的电脑---属性---设备管理器---处理器,查看处理器个数