[BZOJ 1500] 维护序列
Link:
Solution:
可能平衡树维护序列的所有操作都在这了吧……
对序列的维护$fhq treap$和$Splay$都能做
有几个注意点:
1、维护序列时始终记得第$k$大指的是序号,与权值无关
2、注意对0的初始化,毕竟如果无叶子结点时会用到
3、如果数据总量过大要数据回收,用队列记录被删除的节点,同时记得将儿子信息初始化!
4、如果求最大子序列和,一般要维护$lmx,rmx$来求解
如果同时还有翻转操作,记得将$lmx$和$rmx$也要翻转!
6、对$Treap$的初始化时并不需要基于随机的旋转操作,直接构造就好了
要明白随机的旋转目的是为了保证期望树高,如果已经构造得最优了自然不必旋转了
Code:
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define lc s[x][0]
#define rc s[x][1]
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=5e5+,INF=<<;
char op[];queue<int> q;
int spin[MAXN],cov[MAXN],sum[MAXN],mx[MAXN],lmx[MAXN],rmx[MAXN];
int rt,n,m,num,cnt,dat[MAXN],s[MAXN][],pri[MAXN],sz[MAXN],val[MAXN]; int newnode(int x)
{
int cur;
if(!q.empty()) cur=q.front(),q.pop();
else cur=++cnt; sz[cur]=;pri[cur]=rand();
s[cur][]=s[cur][]=;//重用节点后记得清零
val[cur]=sum[cur]=mx[cur]=lmx[cur]=rmx[cur]=x;
spin[cur]=;cov[cur]=INF;return cur;
} void rotate(int x)
{
swap(s[x][],s[x][]);
swap(lmx[x],rmx[x]);spin[x]^=;
}
void modify(int x,int k)
{//记得更新所有数据!
val[x]=k;cov[x]=k;
sum[x]=sz[x]*k;
mx[x]=max(sum[x],val[x]);
lmx[x]=rmx[x]=max(,sum[x]);
}
void pushdown(int x)
{
if(spin[x])
{if(lc) rotate(lc);if(rc) rotate(rc);}
if(cov[x]!=INF)
{if(lc) modify(lc,cov[x]);if(rc) modify(rc,cov[x]);}
spin[x]=;cov[x]=INF;
}
void pushup(int x)
{
if(!x) return;
sz[x]=sz[lc]+sz[rc]+;
sum[x]=sum[lc]+sum[rc]+val[x];
mx[x]=max(mx[lc],mx[rc]);
mx[x]=max(mx[x],max(,rmx[lc])+val[x]+max(,lmx[rc]));
lmx[x]=max(lmx[lc],sum[lc]+val[x]+max(,lmx[rc]));
rmx[x]=max(rmx[rc],sum[rc]+val[x]+max(,rmx[lc]));
} int build(int l,int r)
{
if(l>r) return ;
int mid=(l+r)>>;
int x=newnode(dat[mid]);
s[x][]=build(l,mid-);
s[x][]=build(mid+,r);
pushup(x);return x;
}
void split(int x,int k,int &a,int &b)
{
if(!x){a=b=;return;}
pushdown(x);
if(k<=sz[lc]) b=x,split(lc,k,a,lc);
else a=x,split(rc,k-sz[lc]-,rc,b);
pushup(x);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
pushdown(x);pushdown(y);
if(pri[x]<pri[y])
{
s[x][]=merge(s[x][],y);
pushup(x);return x;
}
else
{
s[y][]=merge(x,s[y][]);
pushup(y);return y;
}
} void reuse(int x)
{//记录重用节点
if(!x) return;
q.push(x);
reuse(lc);reuse(rc);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&dat[i]);
mx[]=val[]=-INF;rt=build(,n); int num,pos,k,x,y,z;
for(int i=;i<=m;i++)
{
scanf("%s",op+);
if(op[]!='X') scanf("%d%d",&pos,&num);
if(op[]=='I')
{
for(int j=;j<=num;j++)
scanf("%d",&dat[j]);
z=build(,num);
split(rt,pos,x,y);
rt=merge(x,merge(z,y));
}
else if(op[]=='D')
{
split(rt,pos-,x,y);
split(y,num,y,z);
reuse(y);rt=merge(x,z);
}
else if(op[]=='K')
{
scanf("%d",&k);
split(rt,pos-,x,y);
split(y,num,y,z);
modify(y,k);
rt=merge(x,merge(y,z));
}
else if(op[]=='R')
{
split(rt,pos-,x,y);
split(y,num,y,z);rotate(y);
rt=merge(x,merge(y,z));
}
else if(op[]=='G')
{
split(rt,pos-,x,y);
split(y,num,y,z);
printf("%d\n",sum[y]);
rt=merge(x,merge(y,z));
}
else printf("%d\n",mx[rt]);
}
return ;
}
[BZOJ 1500] 维护序列的更多相关文章
- bzoj 1500 维修序列
Written with StackEdit. Description 请写一个程序,要求维护一个数列,支持以下 \(6\) 种操作: 请注意,格式栏 中的下划线' _ '表示实际输入文件中的空格 I ...
- bzoj 1798 维护序列seq
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题解: 高级一点的线段树,加上了区间乘法运算,则需要增加一个数组mulv记录乘的因数 ...
- bzoj 1798 维护序列seq 线段树
裸的线段树,注意标签下放就行了 多么痛的领悟,一定要开int64 /************************************************************** Pro ...
- bzoj 维护序列seq(双标记线段树)
Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 4184 Solved: 1518[Submit][Status][Discus ...
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )
线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 7773 Solved: 2792[Submit ...
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...
- BZOJ 1251 Splay维护序列
思路: splay维护序列的裸题 啊woc调了一天 感谢yzy大佬的模板-- //By SiriusRen #include <cstdio> #include <cstring&g ...
- Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...
随机推荐
- 【BZOJ】4430: [Nwerc2015]Guessing Camels赌骆驼
[题意]给定三个长度为n的排列,求在三个排列中顺序相同的数对个数. [算法]逆序对 [题解]很容易联想到NOIP火柴排队,涉及顺序问题显然和逆序对息息相关. 一个数对如果在三个排列中顺序不同,一定是1 ...
- IOException while loading persisted sessions:
严重: IOException while loading persisted sessions: java.io.EOFException java.io.EOFException at java. ...
- 顺序图(Sequence Diagram)
顺序图(Sequence Diagram): 是一种强调对象间消息传递次序的交互图,又称为时序图或序列图.描述了在一个用例或操作的执行过程中对象如何通过消息相互交互,说明了消息如何在对象之间被发送和接 ...
- rabbitmq之配置文件详解(二)
前言 前面介绍了erlang环境的安装和rabbitmq环境安装,接下来对rabbitmq详细配置: 设置配置文件 rabbitmq的系统配置文件一般是rabbitmq.conf,可以登录后台查看它的 ...
- 【Python学习】程序运行完发送邮件提醒
有时候我们运行一个需要跑很长时间的程序,不管是在云主机还是本地主机上运行,我们都不可能一直守在电脑面前等.所以想到使用邮件来通知提醒. 示例代码如下 # -*- coding: utf-8 -*- # ...
- C后端设计开发 - 第4章-武技-常见轮子下三路
正文 第4章-武技-常见轮子下三路 后记 如果有错误, 欢迎指正. 有好的补充, 和疑问欢迎交流, 一块提高. 在此谢谢大家了. Moonlight Shadow 纪念那个我爱的, 被我感动的女孩 ...
- javascript 实现图片放大镜功能
淘宝上经常用到的一个功能是利用图片的放大镜功能来查看商品的细节 下面我们来实现这样一个功能吧,原理很简单: 实现一个可以随鼠标移动的虚框 在另外一个块中对应显示虚框中的内容 实现思路: 虚框用css中 ...
- hive学习(一)hive架构及hive3.1.1三种方式部署安装
1.hive简介 logo 是一个身体像蜜蜂,头是大象的家伙,相当可爱. Hive是一个数据仓库基础工具在Hadoop中用来处理结构化数据.它架构在Hadoop之上,总归为大数据,并使得查询和分析方便 ...
- Django基础之forms组件中的ModelForm组件
Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...
- Intersection of Two Linked Lists——经典问题
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...