BZOJ 3064 Tyvj 1518 CPU监控

题解:历史最值线段树

参见吉司机的论文

还是不熟,自己打打不出来

维护当前和历史两套标记,最大值,加法标记,减法标记

每到一个节点先pushdown(不知道为什么)

正确性不是很理解QWQ

还是自己太弱了

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100009;
typedef long long Lint;
const Lint inf=1000000000000000;

int n,m;
Lint a[maxn];

struct SegmentTree{
	int l,r;
	Lint mx[2],tag[2],st[2];
}tree[maxn<<3];

void pushup(int now){
	tree[now].mx[0]=max(tree[now<<1].mx[0],tree[now<<1|1].mx[0]);
	tree[now].mx[1]=max(tree[now<<1].mx[1],tree[now<<1|1].mx[1]);
}
void pushdown(int now){
	int son;
	for(int i=0;i<=1;++i){
		son=now<<1|i;
		tree[son].mx[0]=max(tree[son].mx[0],max(tree[now].st[0],tree[son].mx[1]+tree[now].tag[0]));
		if(tree[son].st[1]==-inf){
			tree[son].tag[0]=max(tree[son].tag[0],tree[son].tag[1]+tree[now].tag[0]);
		}else{
			tree[son].st[0]=max(tree[son].st[0],tree[son].st[1]+tree[now].tag[0]);
		}
		if(tree[now].tag[1]){
			if(tree[son].st[1]!=-inf)tree[son].st[1]+=tree[now].tag[1];
			else tree[son].tag[1]+=tree[now].tag[1];
			tree[son].mx[1]+=tree[now].tag[1];
		}
		if(tree[now].st[1]!=-inf){
			tree[son].st[1]=tree[son].mx[1]=tree[now].st[1];
			tree[son].tag[1]=0;
		}
		tree[son].st[0]=max(tree[son].st[0],max(tree[son].st[1],tree[now].st[0]));
		tree[son].tag[0]=max(tree[son].tag[0],tree[son].tag[1]);
	}
	tree[now].tag[0]=tree[now].tag[1]=0;
	tree[now].st[0]=tree[now].st[1]=-inf;
}

void BuildTree(int now,int l,int r){
	tree[now].l=l;tree[now].r=r;
	tree[now].tag[0]=tree[now].tag[1]=0;
	tree[now].st[0]=tree[now].st[1]=-inf;
	if(l==r){
		tree[now].mx[0]=tree[now].mx[1]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	BuildTree(now<<1,l,mid);
	BuildTree(now<<1|1,mid+1,r);
	pushup(now);
}

void Updatasec(int now,int ll,int rr,Lint x,int opty){
	if(tree[now].l!=tree[now].r)pushdown(now);
	if(tree[now].l>=ll&&tree[now].r<=rr){
		if(opty==0){
			tree[now].mx[1]+=x;tree[now].tag[1]+=x;tree[now].tag[0]=x;
		}else{
			tree[now].st[1]=tree[now].st[0]=tree[now].mx[1]=x;
		}
		tree[now].mx[0]=max(tree[now].mx[0],tree[now].mx[1]);
		return;
	}
	int mid=(tree[now].l+tree[now].r)>>1;
	if(ll<=mid)Updatasec(now<<1,ll,rr,x,opty);
	if(rr>mid)Updatasec(now<<1|1,ll,rr,x,opty);
	pushup(now);
}

Lint Querymax(int now,int ll,int rr,int opty){
	if(tree[now].l!=tree[now].r)pushdown(now);
	if(tree[now].l>=ll&&tree[now].r<=rr){
		return tree[now].mx[opty];
	}
	Lint ans=-inf;
	int mid=(tree[now].l+tree[now].r)>>1;
	if(ll<=mid)ans=max(ans,Querymax(now<<1,ll,rr,opty));
	if(rr>mid)ans=max(ans,Querymax(now<<1|1,ll,rr,opty));
	return ans;
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
	BuildTree(1,1,n);
	scanf("%d",&m);
	while(m--){
		char opty=getchar();
		while(opty<‘A‘||opty>‘Z‘)opty=getchar();
		int l,r,x;
		scanf("%d%d",&l,&r);
		if(opty==‘Q‘)printf("%lld\n",Querymax(1,l,r,1));
		if(opty==‘A‘)printf("%lld\n",Querymax(1,l,r,0));
		if(opty==‘P‘){
			scanf("%d",&x);Updatasec(1,l,r,x,0);
		}
		if(opty==‘C‘){
			scanf("%d",&x);Updatasec(1,l,r,x,1);
		}
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zzyer/p/8456403.html

时间: 2024-10-22 05:22:29

BZOJ 3064 Tyvj 1518 CPU监控的相关文章

[补档][Tyvj 1518]CPU监控

题目 Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源--这些事有的会让做这件事的这段时间内CPU使用率增加或减少一个值:有的事还会直接让CPU使用率变为一个值. 当然Bob会询问:在之前给出的事件影响下,CPU在某段时间内,使用率最高是多少.有时候Bob还会好奇地询问,在某段时间内CPU曾经的最高使用率是多少. 为了使计

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: Tyvj 1518 CPU监控

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

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

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

题目链接 \(Description\) 有一个长为n的序列Ai,要求支持查询[l,r]的最值.历史最值,区间加/重设 \(Solution\) 线段树,每个点再维护一个历史(从0到现在)最大值.历史(从上次下传标记到现在)最大的set,add标记 PushDown时肯定是先下放历史标记,之后再用当前标记更新 /* 要记得当要PushDown某个点时,last,now的val都是历史的(下传前),所以now.v + last.add就是下传前值+[下传前到现在]一次最大的修改的值 不能只在Set

cpu监控数据及cpu几核关系

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