洛谷 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\) 个结点的树, ...
随机推荐
- CDHD驱动器——ServoStudio配置高创伺服速度模式不转
1. 摘要 速度模式(LED灯显示为0)时,电机不转,但是在位置模式(LED灯显示为8)却可以正常运转. 2. 设置 设置commode=1,fbitprd=1,fbitidx=-3,modmode= ...
- hdu 1512 Monkey King —— 左偏树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 很简单的左偏树: 但突然对 rt 的关系感到混乱,改了半天才弄对: 注意是多组数据! #includ ...
- Python三次登陆
题目:Python实现三次登陆 不要急于马上把三次登陆写出来,一定要将复杂的程序简单化,必须一步一步地去扩展,这样才保证不会出错. 步骤一:实现简单的一次登陆 # 事先定义 user = 'dark_ ...
- webpack的初步使用(01)
webpack:1.安装:在项目文件下先npm init初始化,一路回车2.进入到建立的项目下:cd projectname3.安装webpack:npm install webpack --save ...
- [App Store Connect帮助]三、管理 App 和版本(1)添加 App 至您的帐户
在向 App Store Connect 上传您 App 的构建版本之前,您必须先在您的 App Store Connect 帐户内新建一个 App. 如果您想将 iOS App 和 Apple TV ...
- 简单入门构建spark1.6.1源码环境
能有源码的辅助,加上自身的修炼,能起到很好的作用! 对于初学者,不建议,一上来看源码. 下载 http://archive.apache.org/dist/spark/spark-1.6.1/
- 记Spring下autowire为name时的一个现象
当autowire为byname时,假如有一个名为“user”的component,恰巧还有另一个属性为“user”,它的set方法为setUser(User user),Spring会强行把comp ...
- sql server 大数据跨服务器迁移表数据——使用链接服务器
1.创建链接服务器(填写链接服务器.远程登录.使用密码) 2.188.188.1.177是远程的 select count(*) from [188.188.1.177].BigDataAnalysi ...
- c#——值类型与引用类型
值类型传的是值 引用类型传的是地址
- dotnetnuke 头像调用 头像缩放
public static string GetProfileImage(int userId, int width, int height) { ...