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 ...
随机推荐
- jQuery生成QRcode二维码
jQuery生成QRcode二维码示例 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- item 11: 比起private undefined function优先使用deleted function
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果你为其他开发者提供代码,并且你想阻止他们调用一个特定的函数,你 ...
- linux下用户操作记录审计环境的部署记录
通常,我们运维管理人员需要知道一台服务器上有哪些用户登录过,在服务器上执行了哪些命令,干了哪些事情,这就要求记录服务器上所用登录用户的操作信息,这对于安全维护来说很有必要.废话不多说了,下面直接记录做 ...
- Linux下FTP环境部署梳理(vsftpd和proftpd)
在日常运维工作中,常部署到的FTP是vsftpd和proftd.之前写了Linux下FTP虚拟账号环境部署总结,下面简单说下本地用户下的FTP环境部署过程: 简单梳理下FTP主动和被动两种工作模式: ...
- 状态模式-State-订单状态
JAVA设计模式-状态模式-State-订单状态 21. State(状态) 意图: 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 解释: 比如说对订单的提交,第一 ...
- win10装MySQL5.7
越来越发现装MySQL很费劲啊,装了N次,都很懵逼,找对的解决方案很重要. Mysql5.7下载地址:http://xiazai.zol.com.cn/detail/4/33431.shtml 安装步 ...
- 链表数据结构(C/C++语言实现)
注意:没有使用malloc和free:加了一个头文件,用于清屏和暂停:还有就是一个错误特别容易被忽略,那就是主函数中声明了LinkList p,然后就直接创建链表,忘了给p分配空间.一定要先初始化链表 ...
- Jquery ajax 数据更新
$(function(){ var $personWifePs=$("#wife-money tbody tr"); var $personWife=$("#wife-m ...
- Linux文件权限属性后面有个点
坑啊,新上的机器,监控怎么都不好使,各种报错说:没有权限 什么情况? 仔细查看,发现文件权限属性后面怎么多了个点,类似如下: 这是什么? 原来: 开启了SELinux功能的Linux系统就会有这个点. ...
- js 消息框
消息框有三種:警告框.提示框.確認框 警告框: 確保用戶可以得到某些信息. 點擊確定以後,才能繼續後續操作. alert("不好") 確認框: 請用戶確認或者接受某些信息. 點擊確 ...