[BZOJ3064][Tyvj1518]CPU监控
来源:互联网 发布:淘宝冲量促销什么意思? 编辑:程序博客网 时间:2024/05/21 06:46
题目大意
给定一个长度为
题目分析
参考吉如一的2016年国家集训队论文《区间最值操作与历史最值问题》,里面讲得很清楚了。
一个重要的思路是,在一个点没有被赋值操作影响时,只需要维护区间加标记,在一个点被赋值操作影响过之后,所有操作都可以看成赋值操作。
线段树每个点维护四个标记,两个是正常的区间加与赋值标记,还有两个,分别代表一个点在上一次标记下传至今最大的区间加标记和赋值标记。然后各种讨论合并。细节自己脑补吧。
时间复杂度
代码实现
标记处理代码比线段树长系列。
#include <iostream>#include <climits>#include <cstdio>#include <cctype>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}int buf[30];void write(int x){ if (x<0) putchar('-'),x=-x; for (;x;x/=10) buf[++buf[0]]=x%10; if (!buf[0]) buf[++buf[0]]=0; for (;buf[0];putchar('0'+buf[buf[0]--]));}const int INF=INT_MAX;const int N=100050;int a[N];int n,q;struct segment_tree{ int pre[N<<2][2],tag[N<<2][2]; int h[N<<2],v[N<<2]; void add_(int x,int delta) { h[x]=max(h[x],v[x]+delta); if (tag[x][1]!=-INF) pre[x][1]=max(pre[x][1],tag[x][1]+delta); else pre[x][0]=max(pre[x][0],tag[x][0]+delta); } void assign_(int x,int edit){h[x]=max(h[x],edit),pre[x][1]=max(pre[x][1],edit);} void add(int x,int delta) { h[x]=max(h[x],v[x]+=delta); if (tag[x][1]!=-INF) pre[x][1]=max(pre[x][1],tag[x][1]+=delta); else pre[x][0]=max(pre[x][0],tag[x][0]+=delta); } void assign(int x,int edit){h[x]=max(h[x],v[x]=edit),tag[x][1]=edit,pre[x][1]=max(pre[x][1],edit);} void clear(int x,int l,int r) { if (pre[x][0]) { if (l!=r) add_(x<<1,pre[x][0]),add_(x<<1|1,pre[x][0]); pre[x][0]=0; } if (pre[x][1]!=-INF) { if (l!=r) assign_(x<<1,pre[x][1]),assign_(x<<1|1,pre[x][1]); pre[x][1]=-INF; } if (tag[x][0]) { if (l!=r) add(x<<1,tag[x][0]),add(x<<1|1,tag[x][0]); tag[x][0]=0; } if (tag[x][1]!=-INF) { if (l!=r) assign(x<<1,tag[x][1]),assign(x<<1|1,tag[x][1]); tag[x][1]=-INF; } } void update(int x){v[x]=max(v[x<<1],v[x<<1|1]),h[x]=max(h[x<<1],h[x<<1|1]);} void modify(int x,int st,int en,int l,int r,int y,bool tp) { clear(x,l,r); if (st==l&&en==r) { if (tp) assign(x,y); else add(x,y); clear(x,l,r); return; } int mid=l+r>>1; if (en<=mid) modify(x<<1,st,en,l,mid,y,tp); else if (mid+1<=st) modify(x<<1|1,st,en,mid+1,r,y,tp); else modify(x<<1,st,mid,l,mid,y,tp),modify(x<<1|1,mid+1,en,mid+1,r,y,tp); update(x); } int query(int x,int st,int en,int l,int r,bool tp) { clear(x,l,r); if (st==l&&en==r) return tp?h[x]:v[x]; int mid=l+r>>1; if (en<=mid) return query(x<<1,st,en,l,mid,tp); else if (mid+1<=st) return query(x<<1|1,st,en,mid+1,r,tp); else return max(query(x<<1,st,mid,l,mid,tp),query(x<<1|1,mid+1,en,mid+1,r,tp)); } void build(int x,int l,int r) { pre[x][0]=tag[x][0]=0,pre[x][1]=tag[x][1]=-INF; if (l==r) { h[x]=v[x]=a[l]; return; } int mid=l+r>>1; build(x<<1,l,mid),build(x<<1|1,mid+1,r),update(x); }}t;int main(){ freopen("monitor.in","r",stdin),freopen("monitor.out","w",stdout); n=read(); for (int i=1;i<=n;++i) a[i]=read(); t.build(1,1,n); for (q=read();q--;) { char opt=getchar(); while (!isalpha(opt)) opt=getchar(); int x=read(),y=read(); if (opt=='Q'||opt=='A') write(t.query(1,x,y,1,n,opt=='A')),putchar('\n'); else t.modify(1,x,y,1,n,read(),opt=='C'); } fclose(stdin),fclose(stdout); return 0;}
0 0
- [BZOJ3064][Tyvj1518]CPU监控
- 【BZOJ3064】【Tyvj1518】CPU监控 裸线段树
- 【bzoj3064】【Tyvj 1518 CPU监控】
- BZOJ3064: Tyvj 1518 CPU监控
- [bzoj3064]Tyvj 1518 CPU监控 线段树&排行榜垫底留念
- cpu 监控
- CPU监控
- 12.1.3 CPU监控
- python监控cpu
- Linux CPU 监控脚本
- 2 CPU 性能监控
- android 监控cpu
- cpu top监控脚本
- CPU 内存 磁盘监控
- 服务器性能监控--cpu
- Python监控CPU情况
- 【C#】CPU监控
- mpstate监控CPU详解
- sqoop基本配置与导入导出学习笔记 (Draft)
- 附录篇A——重要的热键[Tab],[Ctrl]-c,[ctrl]-d
- asynctaskdemo
- java中的继承
- write() argument must be str, not bytes
- [BZOJ3064][Tyvj1518]CPU监控
- poj3026Borg Maze_最小生成树(广搜+prim算法)
- #define #ifndef #if
- 页面进入显示点击按钮再查数据库展现列表
- Flink DataSet API Programming Guide学习&译文(未完待续)
- 【LeetCode】 160. Intersection of Two Linked Lists C语言
- 数据库
- 文章标题
- iOS之正则表达式的使用和谓词(NSPredicate)的使用(三)