BZOJ 3064 Tyvj 1518 CPU监控 线段树维护历史最大值
来源:互联网 发布:程序员鼓励师王牧牧 编辑:程序博客网 时间:2024/06/05 08:49
题目大意:给出一个数列要求支持:查询区间最大值,查询区间历史最大值,区间加,区间修改
除了历史最值都是最裸的线段树…
如果上最裸的线段树维护这个东西,在标记下推的时候可能把最值直接推没了…
看看怎么维护这个最值
在每个线段树结点上多维护两个量:历史最大的加法标记,历史最大的修改标记
更新子结点的历史最大值:当前结点的历史加法;当前结点历史修改;子结点的当前最大值
更新子结点的历史加法:当前结点的历史加法;子结点的当前加法
更新子结点的历史修改:当前结点的当前覆盖;子结点的历史覆盖
其他的都正常更新就行…
0表示现在,1表示历史
#include <cstdio>#include <algorithm>#define N 100005#define INF (1ll<<60)using namespace std;typedef long long LL;struct Node { Node* ch[2]; int l,r; LL maxx[2],add_mark[2],change_mark[2]; Node() {} Node(int _l,int _r):l(_l),r(_r) { maxx[0]=maxx[1]=0; add_mark[0]=add_mark[1]=0; change_mark[0]=change_mark[1]=-INF; } void* operator new(size_t) { static Node *C,*mempool; if(mempool==C) mempool=(C=new Node[1<<20])+(1<<20); return C++; } void add(int v) { maxx[0]+=v; if(change_mark[0]!=-INF) change_mark[0]+=v; else add_mark[0]+=v; add_mark[1]=max(add_mark[1],add_mark[0]); maxx[1]=max(maxx[1],maxx[0]); return ; } void change(int v) { change_mark[0]=maxx[0]=v; add_mark[0]=0; change_mark[1]=max(change_mark[1],change_mark[0]); maxx[1]=max(maxx[1],maxx[0]); return ; } void pushdown() { for(int i=0;i<2;++i) { ch[i]->maxx[1]=max(ch[i]->maxx[1],max(change_mark[1],ch[i]->maxx[0]+add_mark[1])); if(ch[i]->change_mark[0]==-INF) ch[i]->add_mark[1]=max(ch[i]->add_mark[1],ch[i]->add_mark[0]+add_mark[1]); else ch[i]->change_mark[1]=max(ch[i]->change_mark[1],ch[i]->change_mark[0]+add_mark[1]); if(add_mark[0]) ch[i]->add(add_mark[0]); if(change_mark[0]!=-INF) ch[i]->change(change_mark[0]); ch[i]->change_mark[1]=max(ch[i]->change_mark[1],change_mark[1]); } add_mark[0]=add_mark[1]=0; change_mark[0]=change_mark[1]=-INF; return ; } void maintain() { maxx[0]=max(ch[0]->maxx[0],ch[1]->maxx[0]); maxx[1]=max(ch[0]->maxx[1],ch[1]->maxx[1]); return ; }}*root;int n,m,a[N];void init(Node*& o,int l,int r) { o=new Node(l,r); if(l==r) { o->maxx[0]=o->maxx[1]=a[l]; return ; } int mid=l+r>>1; init(o->ch[0],l,mid), init(o->ch[1],mid+1,r); o->maintain(); return ;}LL Query(Node* o,int l,int r,int mode) { if(o->l==l && o->r==r) return o->maxx[mode]; o->pushdown(); int mid=o->l+o->r>>1; if(r<=mid) return Query(o->ch[0],l,r,mode); if(l>mid) return Query(o->ch[1],l,r,mode); return max(Query(o->ch[0],l,mid,mode),Query(o->ch[1],mid+1,r,mode));}void Modify(Node* o,int l,int r,int v,int mode) { if(o->l==l && o->r==r) { if(!mode) o->add(v); else o->change(v); return ; } o->pushdown(); int mid=o->l+o->r>>1; if(r<=mid) Modify(o->ch[0],l,r,v,mode); else if(l>mid) Modify(o->ch[1],l,r,v,mode); else Modify(o->ch[0],l,mid,v,mode), Modify(o->ch[1],mid+1,r,v,mode); o->maintain(); return ;}int main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",a+i); init(root,1,n); for(scanf("%d",&m);m;m--) { char mode[2]; int x,y,z; scanf("%s%d%d",mode,&x,&y); if(mode[0]=='Q') printf("%lld\n",Query(root,x,y,0)); if(mode[0]=='A') printf("%lld\n",Query(root,x,y,1)); if(mode[0]=='P') scanf("%d",&z), Modify(root,x,y,z,0); if(mode[0]=='C') scanf("%d",&z), Modify(root,x,y,z,1); } return 0;}
阅读全文
1 0
- BZOJ 3064 Tyvj 1518 CPU监控 线段树维护历史最大值
- bzoj 3064: Tyvj 1518 CPU监控 线段树维护历史最大值
- bzoj 3064: Tyvj 1518 CPU监控 (线段树)
- [bzoj 3064] Tyvj 1518 CPU监控:线段树的Lazy tag
- [bzoj3064]Tyvj 1518 CPU监控 线段树&排行榜垫底留念
- 3064: Tyvj 1518 CPU监控
- 【bzoj3064】【Tyvj 1518 CPU监控】
- BZOJ3064: Tyvj 1518 CPU监控
- hdu1754线段树维护区间最大值
- 线段树维护区间最大值hdu1754
- 二维线段树维护最大值hdu1823
- poj3264 线段树维护最大值最小值
- spojGSS1 线段树维护区间和最大值
- [SPLAY维护区间][BZOJ 3223][TYVJ 1729]文艺平衡树
- BZOJ 2124 线段树维护hash值
- bzoj 2957 楼房重建 线段树维护
- BZOJ 5039: [Jsoi2014]序列维护 线段树
- zoj 3363 线段树维护最大值 Alice's present
- jq绑定事件的方法区别
- 前台数据通过AJAX传到JAVA后台并存入到txt文件中
- AVL树
- SDC沙盒防泄密
- C#关键词说明
- BZOJ 3064 Tyvj 1518 CPU监控 线段树维护历史最大值
- Python基础概念_11_标准库
- IntelliJ IDEA使用技巧一览表
- Eclipse中修改SVN用户名和密码方法
- SQLite中常用的SQL语句
- Centos部署kubernetes
- 目标检测 Feature Pyramid Networks for Object Detection(FPN)论文笔记
- 数据结构BinaryTree实例(四):二叉树遍历总结(前中后,层次遍历)
- leetcode Integer to Roman(Java)