洛谷 2042 BZOJ 1500 NOI 2005 维护数列
【题意概述】
维护一个数列,要求支持以下6种操作:
 
【题解】
大Boss。。。可以用Treap解决
需要用到垃圾回收、线性建树。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (a[u].l)
#define rs (a[u].r)
using namespace std;
const int maxn=;
int n,m,k,x,y,z,top,root,recs[maxn],bs[maxn];//recs-->recycle_stack, bs-->build_stack
char c,c2;
struct treap{int l,r,size,rnd,v,sum,max,lsum,rsum,num; bool same,rev;}a[maxn];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline int max(int x,int y){return x>y?x:y;}
inline int newnode(int v){a[recs[top--]]=(treap){,,,rand(),v,v,v,v,v,,,}; return recs[top+];}//新建节点
void recycle(int u){if(u) recs[++top]=u,recycle(ls),recycle(rs);}//垃圾回收
inline void reverse(int u){//区间翻转
swap(ls,rs); swap(a[u].lsum,a[u].rsum);
a[ls].rev^=; a[rs].rev^=;
}
inline void set_same(int u,int v){//区间设为同个数
a[u].same=; a[u].v=a[u].num=v; a[u].sum=v*a[u].size;
a[u].max=a[u].lsum=a[u].rsum=(v>=?a[u].sum:v);
}
void down(int u){//下传标记
if(a[u].rev){
if(ls) reverse(ls);
if(rs) reverse(rs);
a[u].rev^=;
}
if(a[u].same){
if(ls) set_same(ls,a[u].num);
if(rs) set_same(rs,a[u].num);
a[u].same=a[u].num=;
}
}
void up(int u){//上传标记
a[u].size=a[ls].size+a[rs].size+;
a[u].sum=a[ls].sum+a[rs].sum+a[u].v;
a[u].max=max(max(a[ls].max,a[rs].max),max(a[ls].rsum,)+a[u].v+max(a[rs].lsum,));
a[u].lsum=max(a[ls].lsum,a[ls].sum+a[u].v+max(a[rs].lsum,));
a[u].rsum=max(a[rs].rsum,a[rs].sum+a[u].v+max(a[ls].rsum,));
}
void split(int u,int k,int &x,int &y){//分裂
down(u);
if(!k){x=; y=u; return;}
if(a[u].size==k){x=u; y=; return;}
if(a[ls].size>=k) split(ls,k,x,ls),y=u;
else split(rs,k-a[ls].size-,rs,y),x=u;
up(u);
}
int merge(int x,int y){//合并
if(!x||!y) return x+y;
if(a[x].rnd<a[y].rnd){down(x); a[x].r=merge(a[x].r,y); up(x); return x;}
else{down(y); a[y].l=merge(x,a[y].l); up(y); return y;}
}
void build(int &root,int n){//线性建树
int bstop=; bs[++bstop]=newnode(read());
for(int i=;i<n;i++){
int now=newnode(read());
while(top&&a[now].rnd<a[bs[bstop]].rnd) up(bs[bstop]),a[now].l=bs[bstop--];
if(bstop) a[bs[bstop]].r=now;
bs[++bstop]=now;
}
while(bstop) up(bs[bstop--]);
root=bs[];
}
void out(int u){
if(ls) out(ls);
printf("%d ",a[u].v);
if(rs) out(rs);
}
void Insert(){//插入
int x,y,insroot=;
split(root,read(),x,y);
build(insroot,read());
root=merge(x,merge(insroot,y));
//out(root);
}
void Delete(){recycle(y); y=;}//删除
void Prepare(){
srand();
for(int i=maxn;i;i--) recs[++top]=i;
a[].max=a[].lsum=a[].rsum=-2e9;
}
int main(){
Prepare();
n=read(); m=read(); build(root,n); //out(root);
//for(int i=1;i<=n;i++) root=merge(root,newnode(read()));
while(m--){
c=getchar(); while(c!='I'&&c!='D'&&c!='K'&&c!='R'&&c!='G'&&c!='X') c=getchar();
c2=getchar(); while(c2!='-'&&c2!=' ') c2=getchar();
if(c=='X'){//max_sum
printf("%d\n",a[root].same?(a[root].num?a[root].num*a[root].size:a[root].num):a[root].max);
continue;
}
if(c=='I'){Insert(); continue;}//insert
split(root,read()-,x,y);
split(y,read(),y,z);
if(c=='D') Delete();//delete
if(c=='K') set_same(y,read());//set_same
if(c=='R') a[y].rev^=,reverse(y);//reverse
if(c=='G') printf("%d\n",a[y].same?a[y].num*a[y].size:a[y].sum);//get_sum
root=merge(merge(x,y),z);
}
return ;
}
洛谷 2042 BZOJ 1500 NOI 2005 维护数列的更多相关文章
- bzoj 1500 [NOI 2005] 维修数列
		题目大意不多说了 貌似每个苦逼的acmer都要做一下这个splay树的模版题目吧 还是有很多操作的,估计够以后当模版了.... #include <cstdio> #include < ... 
- NOI 2005维护数列
		题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 输入输出格式 输入格式: 输入文件的第 1 行包含两个数 N 和 M, ... 
- 洛谷 P1486 BZOJ 1503 NOI 2004  郁闷的出纳员 fhq treap
		思路: 1. 此处的fhq treap的分裂是按照权值分裂然后插入的.将小于k的分为一棵子树,大于等于k的分为另一棵子树. 2. 删除的时候只要将大于等于min的分裂到以root为根的树中,另一部分不 ... 
- BZOJ 1500 洛谷2042维护序列题解
		BZ链接 洛谷链接 这道题真是丧心病狂.... 应该很容易就可以看出做法,但是写代码写的....... 思路很简单,用一个平衡树维护一下所有的操作就好了,重点讲解一下代码的细节 首先如果按照常规写法的 ... 
- 洛谷.2042.[NOI2005]维护数列(Splay)
		题目链接 2017.12.24 第一次写: 时间: 2316ms (1268ms) 空间: 19.42MB (19.5MB)(O2) 注:洛谷测的时间浮动比较大 /* 插入一段数:将这些数先单独建一棵 ... 
- 洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列
		题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ... 
- 洛谷 P2587 BZOJ 1034 [ZJOI2008]泡泡堂
		题目描述 //不知道为什么BZOJ和洛谷都没有这幅图了,大牛们几年前的博客上都有这幅图的,把它贴上来吧 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省 ... 
- 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)
		题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ... 
- 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
		令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ... 
随机推荐
- [NHibernate] 入门实例 NHibernate 3.3 GA + VS2010 +MySQL
			题外话: 中国的技术论坛要赶上stackoverflow的水平.至少还需35年.中国程序猿笔者的特点是:太浮躁,太easy下总结.太自得其乐,虽说写的是为了让别人更好的看.却也演变成了一种" ... 
- 项目中如何使用NuGet添加类库
			在项目上右键-->Manage NuGet Packages Browse 可以去搜索想要添加到项目的类库 Installed 已经添加到项目的类库 Updates 需要更新的类库 
- Dictionary<string, string>是一个泛型使用说明
			Dictionary<string, string>是一个泛型使用说明 Posted on 2010-08-05 15:03 moss_tan_jun 阅读(2273) 评论(0) 编辑 ... 
- HTTP缓存控制  总结
			一.HTTP响应头.请求头中与缓存控制的相关字段 二.一个页面访问缓存的流程 三.三种刷新的实际操作 四.如何设置缓存 一.HTTP响应头.请求头中与缓存控制的相关字段 浏览器向服务器发起请求后,服务 ... 
- Redis学习和应用记录(2)--常用数据类型及命令
			这一节主要介绍Redis支持的数据结构及常用命令. 数据类型 Redis支持多种数据类型的存储,包括字符,列表,集合,有续集合,哈希表,bit数组,超级日志等.下面分别介绍: strings:存储普通 ... 
- null, undefined,"",0,false是什么关系?
			null本质上和0,"",false是一类东西,它们都表示一种数据类型的非值.正如0表示数字类型的非值,""表示字符类型的非值一样,null表示完全空的对象,即 ... 
- [Swift通天遁地]八、媒体与动画-(4)给相机添加CoreImage滤镜效果
			★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ... 
- Akka源码分析-Remote-收消息
			上一遍博客中,我们分析了网络链接建立的过程,一旦建立就可以正常的收发消息了.发送消息的细节不再分析,因为对于本地的actor来说这个过程相对简单,它只是创立链接然后给指定的netty网路服务发送消息就 ... 
- distpicker三级联动,动态改变省市信息
			一.引入3个js文件 <script type="text/javascript" src="js/distpicker.data.js">< ... 
- nginx + php-fpm 运行原理
			一.关于nginx 1.1 简单认知 我们都知道nginx 是web服务器. 也知道 用户访问时通过ip和端口访问 nginx. 那么nginx 是如何 通过php 获取数据并返回数据的呢? 1.2 ... 
