Tyvj 1518 CPU监控——极恶线段树
题目大意:
给定一个区间及其各个元素的初值,要求支持如下操作:
1.区间加
2.区间赋值
3.查询区间最大值
4.查询区间历史最大值
分析:
容易想到线段树,但是细思恶极(仔细想想恶心到了极点)的是,最后查询区间历史最大值的操作。
如果只记录区间历史最大值显然不能下放,如果单纯更新区间加,区间赋值最大值,可能会出现历史最大值更新不及时的情况。如先赋值很大值,未来得及下放,又赋值很小,导致子区间历史最大值不能更新。又如如果区间加只取最大值,可能会只取最大值,导致实际上忽视了一些使区间加变小的操作。
。。。。(此处省略若千字)
所以我们记录如下几点:
1.mx(x)当前区间最大值
2.hx(x)历史区间最大值
3.ad(x)当前区间加
4.ha(x)历史最大区间加
5.ch(x)当前区间赋值
6.hc(x)历史最大区间赋值
注意 :
这里我们所谓的ha,hc是指在上一次pushdown之后,期间进行的操作中的最大值。是可以清零的,不像hx。
初值:ha=ad=0,ch=hc=-inf。
因为每次都先进行pushdown,所以ha、hc直接随着ad、ch更新。
注意的是pushdown中的许多讨论,自己分析清楚。
其实每次都pushdown是很慢的,会tle两个点。
然后就把区间内的l、r不记录了,竟然不开O2水过。
详见代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=+;
const ll inf=1e13;
int root,n,e;
ll a[N];
int cc;
struct node{
ll add,ch;
ll mx,hx;
ll had,hch;//一段时间内最值
#define ad(x) t[x].add
#define ch(x) t[x].ch
#define mx(x) t[x].mx
#define hx(x) t[x].hx
#define ha(x) t[x].had
#define hc(x) t[x].hch
#define l(x) t[x].l
#define r(x) t[x].r
}t[*N];
void pushup(int x)
{
int s1=x<<,s2=x<<|;
mx(x)=max(mx(s1),mx(s2));
hx(x)=max(hx(s1),hx(s2));
}
void build(int x,int L,int R)
{
if(L==R)
{
ad(x)=;ch(x)=-inf;ha(x)=;hc(x)=-inf;
mx(x)=hx(x)=a[L];
return;
}
int mid=(L+R)>>;
ad(x)=;ch(x)=-inf;ha(x)=;hc(x)=-inf;
mx(x)=hx(x)=-inf;
build(x<<,L,mid);
build(x<<|,mid+,R);
pushup(x);
}
void pushdown(int x)
{
for(int i=;i<=;i++)
{
int s=x<<|i;
hx(s)=max(hx(s),max(mx(s)+ha(x),hc(x)));
if(ch(s)!=-inf) hc(s)=max(hc(s),ch(s)+ha(x));
else ha(s)=max(ha(s),ad(s)+ha(x));
if(ad(x))
{
if(ch(s)!=-inf) ch(s)+=ad(x);
else ad(s)+=ad(x);
mx(s)+=ad(x);
}
if(ch(x)!=-inf)
{
mx(s)=ch(s)=ch(x);
ad(s)=;
}
hc(s)=max(hc(s),max(ch(s),hc(x)));
ha(s)=max(ha(s),ad(s));
}
hc(x)=-inf;
ad(x)=;ch(x)=-inf;ha(x)=;
}
void add(int x,int l,int r,int L,int R,ll c)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
ad(x)+=c;ha(x)+=c;
mx(x)+=c;hx(x)=max(mx(x),hx(x));
return;
} int mid=(l+r)>>;
if(L<=mid) add(x<<,l,mid,L,R,c);
if(R>mid) add(x<<|,mid+,r,L,R,c);
pushup(x);
}
void chan(int x,int l,int r,int L,int R,ll c)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
ch(x)=c,mx(x)=c;hc(x)=c;
hx(x)=max(hx(x),mx(x));
return;
}
int mid=(l+r)>>;
if(L<=mid) chan(x<<,l,mid,L,R,c);
if(R>mid) chan(x<<|,mid+,r,L,R,c);
pushup(x);
}
ll qx(int x,int l,int r,int L,int R)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
return mx(x);
}
int mid=(l+r)>>;
ll res=-inf;
if(L<=mid) res=max(res,qx(x<<,l,mid,L,R));
if(R>mid) res=max(res,qx(x<<|,mid+,r,L,R));
return res;
}
ll qh(int x,int l,int r,int L,int R)
{
if(l!=r)pushdown(x);
if(L<=l&&r<=R)
{
return hx(x);
}
int mid=(l+r)>>;
ll res=-inf;
if(L<=mid) res=max(res,qh(x<<,l,mid,L,R));
if(R>mid) res=max(res,qh(x<<|,mid+,r,L,R));
return res;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
root=;
build(,,n);
scanf("%d",&e);
char q;
int x,y;
ll z;
while(e)
{
cin>>q;
if(q=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",qx(root,,n,x,y));
}
else if(q=='A')
{ scanf("%d%d",&x,&y);
printf("%lld\n",qh(root,,n,x,y));
}
else if(q=='P')
{
scanf("%d%d%lld",&x,&y,&z);
add(root,,n,x,y,z);
}
else{
scanf("%d%d%lld",&x,&y,&z);
chan(root,,n,x,y,z);
}
e--;
}
return ;
}
做这个题要有勇于试错的精神,和坚持不懈的意志。
Tyvj 1518 CPU监控——极恶线段树的更多相关文章
- [补档][Tyvj 1518]CPU监控
[Tyvj 1518]CPU监控 题目 Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看 ...
- 【bzoj3064】Tyvj 1518 CPU监控 线段树维护历史最值
题目描述 给你一个序列,支持4种操作:1.查询区间最大值:2.查询区间历史最大值:3.区间加:4.区间赋值. 输入 第一行一个正整数T,表示Bob需要监视CPU的总时间. 然后第二行给出T个数表示在你 ...
- Tyvj 1518 CPU监控(线段树)
题目描述: Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用 ...
- 2018.07.27 bzoj3064: Tyvj 1518 CPU监控(线段树)
传送门 线段树好题. 维护区间加,区间覆盖,区间最大,区间历史最大. 这个东西在国家集训队2016论文集之<区间最值操作与历史最值问题--杭州学军中学 吉如一>中讲的已经很详细了. 简单来 ...
- bzoj3064 Tyvj 1518 CPU监控
Description Bob需要一个程序来监视CPU使用率.这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事. Bob会干很多事,除了跑暴力程序看视频之外,还会做 ...
- bzoj 3064: Tyvj 1518 CPU监控
Description 1.区间加 \(z\) 2.区间覆盖为 \(z\) 3.查询区间最大值 4.查询区间历史最大值 Solution 线段树维护历史最值,思想大致是维护标记出现过的最大值 考虑这种 ...
- BZOJ3064 Tyvj 1518 CPU监控 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3064 题意概括 一个序列,要你支持以下操作: 1. 区间询问最大值 2. 区间询问历史最大值 3. ...
- 3064: Tyvj 1518 CPU监控
注意这题要维护历史最大加和历史最大覆盖 /************************************************************** Problem: 3064 Us ...
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1807 Solved: 772[Submit][Stat ...
随机推荐
- HTML-JS 数组 内置对象
[JS中的数组] 1.数组的基本概念? 数组是在内存空间中连续存储的一组有序数据的集合 元素在数组中的顺序,称为下标.可以使用下标访问数组的每个元素 2.如何声明一个数组 ① 使用字面量声明:var ...
- 数组-在Shell脚本中的基本使用介绍
Shell脚本在运维工作中是极其重要的,而数组在shell脚本里的运用无论是在循环或运算方面都是非常实用的一个环节.下面是对shell脚本中数组方面一些操作在此进行记录,希望能帮助到有兴趣的朋友~1. ...
- Git版本控制器使用总结性梳理
Git为何物?Git 是什么?大家肯定会说不就是版本控制器嘛,是的Git是目前世界上最先进的分布式版本控制系统(没有之一).1)那什么是版本控制器?举个简单的例子,比如我们用Word写文章,那你一定有 ...
- OSGI的WEB开发环境搭建
第一步,搭建OSGI环境: 打开eclipse,点击run->run configration..,配置如下,点击run. 运行结果如下图所示:说明OSGI环境搭建完毕. 第二步:搭建基于OSG ...
- curator 分布式锁InterProcessMutex
写这篇文章的目的主要是为了记录下自己在zookeeper 锁上踩过的坑,以及踩坑之后自己的一点认识; 从zk分布式锁原理说起,原理很简单,大家也应该都知道,简单的说就是zookeeper实现分布式锁是 ...
- 结构体内嵌比较函数bool operator < (const node &x) const {}
直接看别人的链接 [http://www.cnblogs.com/ZERO-/p/9347296.html]
- E. Train Hard, Win Easy
链接 [http://codeforces.com/contest/1043/problem/E] 题意 有n个人,每个人都有做出a,b题的分数,xi,yi,但是有些人是不能组队的,问你每个人和其他能 ...
- C#【结对编程作业】小学数学习题助手
一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...
- 『编程题全队』Beta 阶段冲刺博客四
1.提供当天站立式会议照片一张 2.每个人的工作 (有work item 的ID) (1) 昨天已完成的工作 孙志威: 1.新增添加提醒事项的按钮 2.添加了新建提醒框 3.测试了新的SubTask思 ...
- vuex最简单、最详细的入门文档
如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 . 我在使用基于 vue.js 2.0 的UI框架 ElementUI 开发网站的时候 , 就遇到了这种问题 : 一 ...