[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 老师交给小可可一个维护数列的任务,现在小可 ...
随机推荐
- HDU 1231 最大连续子序列 (dp)
题目链接 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= ...
- Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)
1.列表拷贝 引用是指保存的值为对象的地址.在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些.下面举个例子: 问题描述:已知一个列表, ...
- 【Matlab】绘制饼状统计图
a=tabulate(b); % b为需要绘制饼图的原始数据列,生成新的一个矩阵a label={'1','2','3'} % 设定饼图每块扇形代表的内容 percent=num2str(a(:,3) ...
- mysql主从复制、操作语句
授权 grant replication slave on *.* to slave@192.168.10.64 identified by "123456" 登录测试 mysql ...
- ThinkPHP5 正则验证中有“|”时提示“规则错误”的解决方案
正则规则中有“|”时,会引起解析错误: 'regex:\d{3,4}[\s,-]?\d{7,8}|1[3,4,5,8]\d[\s,-]?\d{4}[\s,-]?\d{4}' 使用数组语法可以解决: [ ...
- codevs 3287 货车运输 NOIP2013提高组
题目链接:http://codevs.cn/problem/3287/ 题解: 和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客 #include< ...
- problems when installed mysql in linux ubuntu
reference:http://www.jb51.net/article/87160.htm?pc 1.ERROR 2002 (HY000): Can't connect to local MySQ ...
- .net页面实时预览图片
<script type="text/javascript"> //获取上传图片的本地路径 function getPath(obj){ if(obj) { if(na ...
- hdu 1533(最小费用最大流)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- linux下输入密码不回显
这几天在做一个登陆的程序,需要将输入的密码屏蔽掉,自己百度,找到了两种方法,先贴下第一种方法, #include<stdio.h> #include<unistd.h> int ...