博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3064 CPU监控
阅读量:5019 次
发布时间:2019-06-12

本文共 2495 字,大约阅读时间需要 8 分钟。

题目链接:

  学习一番线段树的历史标记~

  这道题就是区间加法,区间赋值,要询问区间最大值 和 区间历史最大值的最大值。

  然后这种题就是在现有标记的基础上多弄一套标记,维护这个点出现过的最大的标记。然后下传标记的时候注意要先传历史标记再传现在的标记。

  王队告诉我说,关于历史标记,可以理解成每个节点有过很多标记,可以看成每个节点都有一个标记队列。这样的话,现在的标记就是在维护这个队列的最后一个,历史标记就是这个队列的\(max\)。所以传标记的时候需要先下传历史标记。

  一定要把各种标记想清楚了再写。

  下面贴代码:

#include
#include
#include
#include
#include
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)#define INF (-2147483647)#define maxn 100010using namespace std;typedef long long llg;int n,m,L,R,_nm,_pm,z,_;int nmax[maxn<<2],nadd[maxn<<2],ncov[maxn<<2];//现在的标记int pmax[maxn<<2],padd[maxn<<2],pcov[maxn<<2];//历史标记int getint(){ int w=0;bool q=0; char c=getchar(); while((c>'9'||c<'0')&&c!='-') c=getchar(); if(c=='-') c=getchar(),q=1; while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;}void update(int u){ nmax[u]=max(nmax[u<<1],nmax[u<<1|1]); pmax[u]=max(pmax[u<<1],pmax[u<<1|1]);}void pushdown(int u){ for(int i=0,v;i<2;i++){ v=u<<1|i; pmax[v]=max(pmax[v],nmax[v]+padd[u]); pmax[v]=max(pmax[v],pcov[u]); if(ncov[v]==INF) padd[v]=max(padd[v],nadd[v]+padd[u]); else pcov[v]=max(pcov[v],ncov[v]+padd[u]); if(nadd[u]){ nmax[v]+=nadd[u]; if(ncov[v]==INF) nadd[v]+=nadd[u]; else ncov[v]+=nadd[u]; } if(ncov[u]!=INF){ nmax[v]=ncov[u]; ncov[v]=ncov[u]; nadd[v]=0; pcov[v]=max(pcov[v],pcov[u]); } } padd[u]=nadd[u]=0,pcov[u]=ncov[u]=INF;}void build(int u,int l,int r){ pcov[u]=ncov[u]=INF; int lc=u<<1,lv=u<<1|1,mid=(l+r)>>1; if(l==r) nmax[u]=pmax[u]=getint(); else build(lc,l,mid),build(lv,mid+1,r),update(u);}void query(int u,int l,int r){ if(l!=r) pushdown(u); if(l>=L && r<=R) _nm=max(_nm,nmax[u]),_pm=max(_pm,pmax[u]); else{ int mid=(l+r)>>1; if(L<=mid) query(u<<1,l,mid); if(R>mid) query(u<<1|1,mid+1,r); }}void add(int u,int l,int r){ if(l!=r) pushdown(u); if(l>=L && r<=R) if(_) padd[u]=nadd[u]=z,pmax[u]=max(pmax[u],nmax[u]+=z); else pcov[u]=ncov[u]=z,pmax[u]=max(pmax[u],nmax[u]=z); else{ int mid=(l+r)>>1; if(L<=mid) add(u<<1,l,mid); if(R>mid) add(u<<1|1,mid+1,r); update(u); }}int main(){ File("a"); n=getint(),build(1,1,n); m=getint(); char c; while(m--){ c=getchar(); while(c!='A' && c!='Q' && c!='P' && c!='C') c=getchar(); L=getint(); R=getint(); if(c=='Q' || c=='A'){ _nm=_pm=INF; query(1,1,n); printf("%d\n",c=='Q'?_nm:_pm); } else{ z=getint(); _=c=='P'; add(1,1,n); } } return 0;}

转载于:https://www.cnblogs.com/lcf-2000/p/6575689.html

你可能感兴趣的文章
A Simple Tree Problem
查看>>
Modular Inverse [ZOJ 3609]
查看>>
MySQL性能测试工具之mysqlslap使用详解
查看>>
深入理解jsonp跨域请求原理
查看>>
MySQL学习点滴 --分区表
查看>>
4.6.1 测试基础
查看>>
洛谷 P2486 [SDOI2011]染色
查看>>
oo第三单元总结
查看>>
leetcode : Count and Say [基本功]
查看>>
洛谷 P2485 [SDOI2011]计算器 解题报告
查看>>
Node教程
查看>>
Redis
查看>>
健壮的 Java 基准测试
查看>>
Amd,Cmd, Commonjs, ES6 import/export的异同点
查看>>
Ubuntu 18.04安装arm-linux-gcc交叉编译器
查看>>
django drf 深入ModelSerializer
查看>>
Android---Menu菜单
查看>>
监控Tomcat
查看>>
剑指offer编程题Java实现——面试题4后的相关题目
查看>>
简单的社交网络分析(基于R)
查看>>