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 ...
随机推荐
- CentOS6下OpenLDAP+PhpLdapAdmin基本安装及主从/主主高可用模式部署记录
下面测试的部署机ip地址为:192.168.10.2051)yum安装OpenLDAP [root@openldap-server ~]# yum install openldap openldap- ...
- iOS网络请求安全认证(JWT,RSA)
在网络世界中,安全是一个很重要的问题,以往的HTTP请求已经不能承担这个安全任务,抓包工具一抓,你的所有网络请求全都曝光.当然,你可能会采用加密算法来加密数据,但是这仍然不够. 在移动端和服务器的通信 ...
- Beta阶段爬取数目预估
预计于12月29号能进行Beta版本发布. Beta阶段我们的爬取动作应该更有针对性,在爬取期间如若数据处理小组有需求,会优先爬取数据处理小组提供的种子链接.预估在项目展示之前能够爬取的数目: 普通网 ...
- shiro课程的学习
1.shiro的课程目标 (1)shiro的整体框架 各组件的概念 (2)shiro 认证 授权的过程 (3)shiro自定义的Reaml Filter (4)shiro session 管理 (5) ...
- iOS开发线程安全问题
先来看一下代码: - (void)viewDidLoad { [super viewDidLoad]; self.testStr = @"String initial complete&qu ...
- 个人作业 - Week3 - 案例分析
调研与评测 真实用户采访: 用户姓名: 刘斯盾 用户的背景和需求: 用户是一位计算机专业学生,需要浏览技术博客来扩充自己的学识. 用户使用博客园证明: 产品是否解决用户问题: 在码代码过程中遇到的很多 ...
- Eclipse集成Tomcat报错:java.lang.OutOfMemoryError: PermGen space
Eclipse集成Tomcat报错,使用Spring 4.3 框架,运行一段应用后,控制台报错: Unexpected death of background thread ContainerBack ...
- From CORBA technology To Thrift technology
技术在变,需求不变,把复杂的事情搞简单,而不是相反. 无论CORBA还是Thrift,目标只有一个:一处定义,多处使用,解决的问题只有一个:规范和简化客户端与服务器的通信的开发工作. 是不是和java ...
- Linux标准输入、输出和错误和文件重定向 专题
当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件.由于文件描述符不容易记忆,shell同时也给出了相应的文件名. 下面就是这些文件描述符及它们通常所 ...
- SQLPLUS SQLCMD连接管理oracle sqlserver的简单用法
1. SQLPLUS 与plsql一样,其实不需要安装oracle客户端,只要是有sqlplus的即时客户端 以及将目录放置到path或者是相应的oralce_home变量中即可. 打开运行cmd s ...