[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 老师交给小可可一个维护数列的任务,现在小可 ... 
随机推荐
- 子DIV块中设置margin-top时影响父DIV块位置的解决办法?
			解决方法: 1.修改父元素的高度,增加padding-top样式模拟(padding-top:1px:常用) 2.为父元素添加overflow:hidden:样式即可(完美) 3.为父元素或者子元素声 ... 
- SQL SERVER 创建远程数据库链接  mysql oracle sqlserver
			遇到的坑 在连接Oracle时,因为服务器为10g 32位版本,然后在本地安装了32为10g客户端,然后一直报错[7302.7303],后来下载了12c 64位版本,安装成功后,问题解决 原因:mss ... 
- nodejs 优雅的连接 mysql
			1.mysql 及 promise-mysql nodejs 连接 mysql 有成熟的npm包 mysql ,如果需要promise,建议使用 promise-mysql: npm:https:// ... 
- Atom:优雅迷人的编辑神器
			对于热爱markdown写作的人来说,Atom同样是一款拥有无穷魅力的写作软件.我不怕它无法满足你的需求,就怕你不给一个机会了解它,那么,这将是一场遗憾的错过. 大学的时候,坊间对那些编程高手有一个令 ... 
- python manage.py 命令
			在用命令django‐admin.py startproject <工程目录>建立一个django工程文件时,会生成一个manage.py文件,那么这个manage.py到底可以干嘛呢? ... 
- Linux网络属性配置命令和管理详解
			一.Linux网络属性配置 1.Linux主机接入到网络方式 IP/NETMASK:实现本地网络通信 路由(网关):可以进行跨网络通信 DNS服务器地址:基于主机名的通信,Linux可以有三个DNS地 ... 
- 一台服务器支持多少TCP并发链接
			误区一 1.文件句柄---文件描述符 每开一个链接,都要消耗一个文件套接字,当文件描述符用完,系统会返回can't open so many files 这时你需要明白操作系统对可以打开的最大文件数 ... 
- POJ-1681
			Painter's Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4839 Accepted: 2350 ... 
- Java读写锁(ReentrantReadWriteLock)学习
			什么是读写锁 平时,我们常见的synchronized和Reentrantlock基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,哪怕是读操作.而读写锁是维护了一对锁(一个读锁和一个写锁), ... 
- 使用Guava retryer优雅的实现接口重调机制
			API 接口调用异常, 网络异常在我们日常开发中经常会遇到,这种情况下我们需要先重试几次调用才能将其标识为错误并在确认错误之后发送异常提醒.guava-retry可以灵活的实现这一功能.Guava r ... 
