学了半天平衡树,选择了一道题来写一写,发现题目是裸的splay模板,但是还是写不好,这个的精髓之处在于在数列的某一个位置加入一个数列,类似于treap里面的merge,然后还学到了题解里面的的回收空间做法,利用时间换取空间也是一种非常不错的做法,由于题目中有区间翻转的操作,所以只能用splay来写,然后对于一些区间最大值和区间最大子序列的询问我们可以用类似于线段树的合并操作来维护,总的来说这是一道对于树形数据结构非常好的运用的题目。——by VANE

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e6+;
int n,m,rt,cnt;
int a[N],id[N],fa[N],c[N][];
int sum[N],sz[N],v[N],mx[N],lx[N],rx[N];
bool tag[N],rev[N];
queue<int> q;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') f=-f; ch=getchar();}
while(ch>=''&&ch<='') {x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void pushup(int x)
{
int l=c[x][],r=c[x][];
sum[x]=sum[l]+sum[r]+v[x];
sz[x]=sz[l]+sz[r]+;
mx[x]=max(mx[l],max(mx[r],rx[l]+v[x]+lx[r]));
lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
}
inline void pushdown(int x)
{
int l=c[x][],r=c[x][];
if(tag[x])
{
rev[x]=tag[x]=;
if(l) tag[l]=,v[l]=v[x],sum[l]=v[x]*sz[l];
if(r) tag[r]=,v[r]=v[x],sum[r]=v[x]*sz[r];
if(v[x]>=)
{
if(l) lx[l]=rx[l]=mx[l]=sum[l];
if(r) lx[r]=rx[r]=mx[r]=sum[r];
}
else
{
if(l) lx[l]=rx[l]=,mx[l]=v[x];
if(r) lx[r]=rx[r]=,mx[r]=v[x];
}
}
if(rev[x])
{
rev[x]=;rev[l]^=;rev[r]^=;
swap(lx[l],rx[l]);swap(lx[r],rx[r]);
swap(c[l][],c[l][]);swap(c[r][],c[r][]);
}
}
inline void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l=(c[y][]==x),r=l^;
if(y==k) k=x;else c[z][c[z][]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
inline void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if(c[z][]==y ^ c[y][]==x) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
inline int find(int x,int rk)
{
pushdown(x);
int l=c[x][],r=c[x][];
if(sz[l]+==rk) return x;
if(sz[l]>=rk) return find(l,rk);
return find(r,rk-sz[l]-);
}
inline void recycle(int x)
{
int &l=c[x][],&r=c[x][];
if(l) recycle(l);
if(r) recycle(r);
q.push(x);
fa[x]=l=r=tag[x]=rev[x]=;
}
inline int split(int k,int tot)
{
int x=find(rt,k),y=find(rt,k+tot+);
splay(x,rt);splay(y,c[x][]);
return c[y][];
}
inline void query(int k,int tot)
{
int x=split(k,tot);
printf("%d\n",sum[x]);
}
inline void modify(int k,int tot,int val)
{
int x=split(k,tot),y=fa[x];
v[x]=val;tag[x]=;sum[x]=sz[x]*val;
if(val>=) lx[x]=rx[x]=mx[x]=sum[x];
else lx[x]=rx[x]=,mx[x]=val;
pushup(y);pushup(fa[y]);
}
inline void rever (int k,int tot)
{
int x=split(k,tot),y=fa[x];
if(!tag[x])
{
rev[x]^=;
swap(c[x][],c[x][]);
swap(lx[x],rx[x]);
pushup(y);pushup(fa[y]);
}
}
inline void erase(int k,int tot)
{
int x=split(k,tot),y=fa[x];
recycle(x);c[y][]=;
pushup(y);pushup(fa[y]);
}
inline void build(int l,int r,int f)
{
int mid=l+r>>,now=id[mid],pre=id[f];
if(l==r)
{
mx[now]=sum[now]=a[l];
lx[now]=rx[now]=max(a[l],);
sz[now]=;
}
if(l<mid) build(l,mid-,mid);
if(mid<r) build(mid+,r,mid);
v[now]=a[mid];fa[now]=pre;
pushup(now);
c[pre][mid>=f]=now;
}
inline void insert(int k,int tot)
{
for(int i=;i<=tot;++i) a[i]=read();
for(int i=;i<=tot;++i)
{
if(!q.empty()) id[i]=q.front(),q.pop();
else id[i]=++cnt;
}
build(,tot,);
int z=id[+tot>>];
int x=find(rt,k+),y=find(rt,k+);
splay(x,rt);splay(y,c[x][]);
fa[z]=y;c[y][]=z;
pushup(y);pushup(x);
}
int main()
{
n=read();m=read();
mx[]=a[]=a[n+]=-inf;
for(int i=;i<=n;++i) a[i+]=read();
for(int i=;i<=n+;++i) id[i]=i;
build(,n+,);
rt=n+>>;cnt=n+;
int k,tot,val;char ch[];
while(m--)
{
scanf("%s",ch);
if(ch[]!='M'||ch[]!='X') k=read(),tot=read();
if(ch[]=='I') insert(k,tot);
if(ch[]=='D') erase(k,tot);
if(ch[]=='M')
{
if(ch[]=='X') printf("%d\n",mx[rt]);
else val=read(),modify(k,tot,val);
}
if(ch[]=='R') rever(k,tot);
if(ch[]=='G') query(k,tot);
}
}

NOI2005 维护数列(splay)的更多相关文章

  1. P2042 [NOI2005]维护数列 && Splay区间操作(四)

    到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...

  2. 洛谷 P2042 [NOI2005]维护数列-Splay(插入 删除 修改 翻转 求和 最大的子序列)

    因为要讲座,随便写一下,等讲完有时间好好写一篇splay的博客. 先直接上题目然后贴代码,具体讲解都写代码里了. 参考的博客等的链接都贴代码里了,有空再好好写. P2042 [NOI2005]维护数列 ...

  3. P2042 [NOI2005]维护数列[splay或非旋treap·毒瘤题]

    P2042 [NOI2005]维护数列 数列区间和,最大子列和(必须不为空),支持翻转.修改值.插入删除. 练码力的题,很毒瘤.个人因为太菜了,对splay极其生疏,犯了大量错误,在此记录,望以后一定 ...

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

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

  5. BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)

    手动博客搬家: 本文发表于20180825 00:34:49, 原地址https://blog.csdn.net/suncongbo/article/details/82027387 题目链接: (l ...

  6. 数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列

    339. [NOI2005] 维护数列 时间限制:3 s   内存限制:256 MB [问题描述] 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际 ...

  7. [NOI2005]维护数列(区间splay)

    [NOI2005]维护数列(luogu) 打这玩意儿真是要了我的老命 Description 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文 ...

  8. [NOI2005] 维护数列

    [NOI2005] 维护数列 题目 传送门 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 操作编号 输入文件中的格式 说明 1 ...

  9. Luogu P2042 [NOI2005]维护数列(平衡树)

    P2042 [NOI2005]维护数列 题意 题目描述 请写一个程序,要求维护一个数列,支持以下\(6\)种操作:(请注意,格式栏中的下划线'_'表示实际输入文件中的空格) 输入输出格式 输入格式: ...

随机推荐

  1. (知识扩展)R运用领域一览表

    • Applications and Case Studies - Lessons and Experiences • Big Data Analytics • Biomedical and Heal ...

  2. 母版页 VS shtml—ASP.NET细枝末节(3)

    这算是html的重用吧? 网页很多地方长得一样,也有不一样的地方. 把网页中一样的地方,提取出来,形成一个文档. 在其他网页中引用,是网站开发的一个传统的思维. 当然不同的技术有不同的表现形式. 例如 ...

  3. VS 2010 应用程序无法启动

    其实一般遇到这种问题, 不管是debug还是release, 也不用看提示的内存地址, 首先应该想到库是否包含正确. 一个可能的错误就是32位或64位不匹配的错误. 比如环境变量设的是64位的Open ...

  4. TypeScript在react项目中的实践

    前段时间有写过一个TypeScript在node项目中的实践. 在里边有解释了为什么要使用TS,以及在Node中的一个项目结构是怎样的. 但是那仅仅是一个纯接口项目,碰巧赶上近期的另一个项目重构也由我 ...

  5. okhttp3使用详解

    http://blog.csdn.net/itachi85/article/details/51190687

  6. 无key值的json数组解析

    [    [        {            "cartId": 9223,            "factoryId": 143,          ...

  7. 关于parse_str变量覆盖分析

    这个漏洞有两个姿势.一个是不存在的时候一个是存在的时候. 经过测试该漏洞只在php5.2中存在,其余均不存在. 倘若在parse_str函数使用的代码上方未将其定义那么即存在变量覆盖漏洞否则不行. 还 ...

  8. 28 - 生成器交互-__slots__-未实现异常

    目录 1 生成器交互 2 slots 3 未实现和未实现异常 4 Python的对象模型 1 生成器交互 生成器提供了一个send方法用于动态的和生成器对象进行交互.怎么理解的呢?看下面的例子: de ...

  9. 【swupdate文档 三】SWUpdate: 嵌入式系统的软件升级

    SWUpdate: 嵌入式系统的软件升级 概述 本项目被认为有助于从存储媒体或网络更新嵌入式系统.但是,它应该主要作为一个框架来考虑,在这个框架中可以方便地向应用程序添加更多的协议或安装程序(在SWU ...

  10. caffe Python API 之Inference

    #以SSD的检测测试为例 def detetion(image_dir,weight,deploy,resolution=300): caffe.set_mode_gpu() net = caffe. ...