【题意概述】

  维护一个数列,要求支持以下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 维护数列的更多相关文章

  1. bzoj 1500 [NOI 2005] 维修数列

    题目大意不多说了 貌似每个苦逼的acmer都要做一下这个splay树的模版题目吧 还是有很多操作的,估计够以后当模版了.... #include <cstdio> #include < ...

  2. NOI 2005维护数列

    题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 输入输出格式 输入格式: 输入文件的第 1 行包含两个数 N 和 M, ...

  3. 洛谷 P1486 BZOJ 1503 NOI 2004 郁闷的出纳员 fhq treap

    思路: 1. 此处的fhq treap的分裂是按照权值分裂然后插入的.将小于k的分为一棵子树,大于等于k的分为另一棵子树. 2. 删除的时候只要将大于等于min的分裂到以root为根的树中,另一部分不 ...

  4. BZOJ 1500 洛谷2042维护序列题解

    BZ链接 洛谷链接 这道题真是丧心病狂.... 应该很容易就可以看出做法,但是写代码写的....... 思路很简单,用一个平衡树维护一下所有的操作就好了,重点讲解一下代码的细节 首先如果按照常规写法的 ...

  5. 洛谷.2042.[NOI2005]维护数列(Splay)

    题目链接 2017.12.24 第一次写: 时间: 2316ms (1268ms) 空间: 19.42MB (19.5MB)(O2) 注:洛谷测的时间浮动比较大 /* 插入一段数:将这些数先单独建一棵 ...

  6. 洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  7. 洛谷 P2587 BZOJ 1034 [ZJOI2008]泡泡堂

    题目描述 //不知道为什么BZOJ和洛谷都没有这幅图了,大牛们几年前的博客上都有这幅图的,把它贴上来吧 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省 ...

  8. 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

    题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...

  9. 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理

    令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ...

随机推荐

  1. 【转】Intent传递数据时,可以传递哪些类型数据?

    在Android应用的开发中,如果我们需要在不同的模块(比如不同的Activity之间)之间传递数据,通常有以下两种方法:1. 利用Intent对象携带数据通过查询Intent/Bundle的API文 ...

  2. B1826 [JSOI2010]缓存交换 贪心+离散化+堆

    这个题仔细一想可以直接贪心做,因为队列里下一个出现的早的一定最优.正确性显然.然后我只拿了50,我直接模拟另一个队列暴力修改最后一个点的nxt值,自然会T.但是其实不用修改,直接插入就行了前面的不影响 ...

  3. 对RDD分区的理解

    举个例子: val logFile = "file:///home/soyo/桌面/6.txt" val conf = new SparkConf().setAppName(&qu ...

  4. cookie封装函数(添加,获取,删除)

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  5. php 时间戳和时间的转换

    PHP的时间戳与具体时间转化 三个内置函数: time() //获取UNIX系统时间戳 mktime(hour,minute,second,month,day,year) //将指定时间转化为时间戳 ...

  6. Java的Thread.currentThread().getName() 和 this.getName() 以及 对象.getName()区别???

    最近在看Java多线程这本书,但是发现里面有个概念自己搞不清楚.就是Thread.currentThread().getName() 和 this.getName() 以及 对象.getName()区 ...

  7. 取消安卓listview,scrollview,gridview滑动时候边缘模糊问题

    只需在xml文件里面声明: android:faddingEdge = "none" android:faddingEdgelenth = "0dp" andr ...

  8. Spring思维课程导图——bean属性的设置

  9. [转]mysql视图学习总结

    转自:http://www.cnblogs.com/wangtao_20/archive/2011/02/24/1964276.html 一.使用视图的理由是什么?1.安全性.一般是这样做的:创建一个 ...

  10. Scala-基础-数据类型

    import junit.framework.TestCase import org.junit.Test import scala.runtime.RichByte //数据类型 class Dem ...