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. PHP正则 贪婪匹配与非贪婪匹配

    $str = ".abcdeabcde"; preg_match('/a.+?e/', $str, $match); print_r($match); Array ( [0] =& ...

  2. Spring Boot 中使用 MyBatis 整合 Druid 多数据源

    2017 年 10 月 20 日   Spring Boot 中使用 MyBatis 整合 Druid 多数据源 本文将讲述 spring boot + mybatis + druid 多数据源配置方 ...

  3. Chinese Rings (九连环+矩阵快速幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2842 题目: Problem Description Dumbear likes to play th ...

  4. vim 以16进制进行文件编辑

    用 vim中二进制文件的编辑是先通过外部程序xxd来把文件dump成其二进制的文本形式,然后就可以按通常的编辑方式对文件进行编辑,编辑完成后再用xxd 转化为原来的形式即可. 可分如下几步进行: (1 ...

  5. MFC不同工程(解决方案)之间对话框资源的复制与重用方法(转)

    原文转自 https://blog.csdn.net/lihui126/article/details/45556687

  6. SourceTree 过期,注册导入许可证

    参考这里:SourceTree过期,需要注册导入 SourceTree License 许可证 很详细 补充: 如果在 SourceTree 软件里注册失败,可以在网页注册. 如果其他邮箱不支持,可以 ...

  7. C C++ 常被人问的问题分析

    正文  -  开始了, 直接扯淡 以下都是自己面试中遇到的常见的问题.如有不妥的地方就当见笑了. 哈哈 1. 谈谈你们服务器的架构吧. 分析: 假如这是第一个问题, 你可以走了. 可能各方面原因他不想 ...

  8. network-scoket

    server: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  9. 【python】r+,w+ 全局变量

    来源:http://www.educity.cn/wenda/352188.html r+:可读可写,若文件不存在,报错w+: 可读可写,若文件不存在,创建文本模式:遇换行符时根据操作系统不同自动转换 ...

  10. 微信小程序实战篇-下拉刷新与加载更多

    下拉刷新 实现下拉刷新目前能想到的有两种方式 1. 调用系统的API,系统有提供下拉刷新的API接口 2. 监听scroll-view,自定义下拉刷新,还记得scroll-view里面有一个binds ...