Link:

BZOJ 1500 传送门

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] 维护序列的更多相关文章

  1. bzoj 1500 维修序列

    Written with StackEdit. Description 请写一个程序,要求维护一个数列,支持以下 \(6\) 种操作: 请注意,格式栏 中的下划线' _ '表示实际输入文件中的空格 I ...

  2. bzoj 1798 维护序列seq

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题解: 高级一点的线段树,加上了区间乘法运算,则需要增加一个数组mulv记录乘的因数 ...

  3. bzoj 1798 维护序列seq 线段树

    裸的线段树,注意标签下放就行了 多么痛的领悟,一定要开int64 /************************************************************** Pro ...

  4. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  5. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  6. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  7. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  8. BZOJ 1251 Splay维护序列

    思路: splay维护序列的裸题 啊woc调了一天 感谢yzy大佬的模板-- //By SiriusRen #include <cstdio> #include <cstring&g ...

  9. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

随机推荐

  1. HDU 1231 最大连续子序列 (dp)

    题目链接 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,  Nj },其中 1 <= ...

  2. Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)

    1.列表拷贝 引用是指保存的值为对象的地址.在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些.下面举个例子: 问题描述:已知一个列表, ...

  3. 【Matlab】绘制饼状统计图

    a=tabulate(b); % b为需要绘制饼图的原始数据列,生成新的一个矩阵a label={'1','2','3'} % 设定饼图每块扇形代表的内容 percent=num2str(a(:,3) ...

  4. mysql主从复制、操作语句

    授权 grant replication slave on *.* to slave@192.168.10.64 identified by "123456" 登录测试 mysql ...

  5. ThinkPHP5 正则验证中有“|”时提示“规则错误”的解决方案

    正则规则中有“|”时,会引起解析错误: 'regex:\d{3,4}[\s,-]?\d{7,8}|1[3,4,5,8]\d[\s,-]?\d{4}[\s,-]?\d{4}' 使用数组语法可以解决: [ ...

  6. codevs 3287 货车运输 NOIP2013提高组

    题目链接:http://codevs.cn/problem/3287/ 题解: 和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客 #include< ...

  7. 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 ...

  8. .net页面实时预览图片

    <script type="text/javascript"> //获取上传图片的本地路径 function getPath(obj){ if(obj) { if(na ...

  9. hdu 1533(最小费用最大流)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  10. linux下输入密码不回显

    这几天在做一个登陆的程序,需要将输入的密码屏蔽掉,自己百度,找到了两种方法,先贴下第一种方法, #include<stdio.h> #include<unistd.h> int ...