BZOJ1500:[NOI2005]维修数列——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1500
https://www.luogu.org/problemnew/show/P2042#sub
请写一个程序,要求维护一个数列,支持以下 6 种操作:请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格
太神啦太神啦,我也不会做,我也是copycat的啊。
https://www.luogu.org/blog/IAmHellWord/solution-p2042
直接看上面这位神犇的题解吧。
#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e6+;
const int INF=1e9;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
char s[];
int fa[N],tr[N][],key[N],size[N],mx[N];
int root,sz,a[N],id[N],sum[N],lx[N],rx[N];
bool rev[N],tag[N];
queue<int>q;
inline void pushup(int x){
int l=tr[x][],r=tr[x][];
sum[x]=sum[l]+sum[r]+key[x];
size[x]=size[l]+size[r]+;
mx[x]=max(mx[l],max(mx[r],rx[l]+key[x]+lx[r]));
lx[x]=max(lx[l],sum[l]+key[x]+lx[r]);
rx[x]=max(rx[r],sum[r]+key[x]+rx[l]);
}
inline void pushdown(int x){
int l=tr[x][],r=tr[x][];
if(tag[x]){
rev[x]=tag[x]=;
if(l)tag[l]=,key[l]=key[x],sum[l]=key[x]*size[l];
if(r)tag[r]=,key[r]=key[x],sum[r]=key[x]*size[r];
if(key[x]>=){
if(l)lx[l]=rx[l]=mx[l]=sum[l];
if(r)lx[r]=rx[r]=mx[r]=sum[r];
}else{
if(l)lx[l]=rx[l]=,mx[l]=key[x];
if(r)lx[r]=rx[r]=,mx[r]=key[x];
}
}
if(rev[x]){
rev[x]=;rev[l]^=;rev[r]^=;
swap(lx[l],rx[l]);swap(lx[r],rx[r]);
swap(tr[l][],tr[l][]);swap(tr[r][],tr[r][]);
}
}
inline bool get(int x){
return tr[fa[x]][]==x;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],which=get(x);
tr[y][which]=tr[x][which^];fa[tr[y][which]]=y;
fa[y]=x;tr[x][which^]=y;fa[x]=z;
if(z)tr[z][tr[z][]==y]=x;
pushup(y);pushup(x);
return;
}
inline void splay(int x,int y){
int f=fa[x];
while(f!=y){
if(fa[f]!=y)rotate(get(x)==get(f)?f:x);
rotate(x);f=fa[x];
}
if(!y)root=x;
return;
}
inline int findx(int x){//找到排名为x的点
int now=root;
while(){
pushdown(now);
if(tr[now][]&&x<=size[tr[now][]])now=tr[now][];
else{
int temp=(tr[now][]?size[tr[now][]]:)+;
if(x==temp)return now;
x-=temp;now=tr[now][];
}
}
}
inline int split(int k,int tot){
int x=findx(k),y=findx(k+tot+);
splay(x,);splay(y,x);
return tr[y][];
}
inline void query(int k,int tot){
int x=split(k,tot);
printf("%d\n",sum[x]);
}
inline void modify(int k,int tot,int v){
int x=split(k,tot),y=fa[x];
key[x]=v;tag[x]=;sum[x]=size[x]*v;
if(v>=)lx[x]=rx[x]=mx[x]=sum[x];
else lx[x]=rx[x]=,mx[x]=v;
pushup(y);pushup(fa[y]);
}
inline void turn(int k,int tot){
int x=split(k,tot),y=fa[x];
if(!tag[x]){
rev[x]^=;
swap(tr[x][],tr[x][]);
swap(lx[x],rx[x]);
pushup(y);pushup(fa[y]);
}
return;
}
inline void recycle(int x){
int &l=tr[x][],&r=tr[x][];
if(l)recycle(l);
if(r)recycle(r);
q.push(x);
fa[x]=l=r=tag[x]=rev[x]=;
}
inline void build(int l,int r,int f){
int mid=(l+r)>>,now=id[mid],pre=id[f];
if(l==r){
mx[now]=sum[now]=a[l];
tag[now]=rev[now]=;
lx[now]=rx[now]=max(a[l],);
size[now]=;
}
if(l<mid)build(l,mid-,mid);
if(mid<r)build(mid+,r,mid);
key[now]=a[mid],fa[now]=pre;
pushup(now);
tr[pre][mid>=f]=now;
}
inline void insert(int k,int tot){
for(int i=;i<=tot;i++)a[i]=read();
for(int i=;i<=tot;i++){
if(!q.empty())id[i]=q.front(),q.pop();
else id[i]=++sz;
}
build(,tot,);
int z=id[(+tot)>>];
int x=findx(k+),y=findx(k+);
splay(x,);splay(y,x);
fa[z]=y;tr[y][]=z;
pushup(y);pushup(x);
return;
}
inline void del(int k,int tot){
int x=split(k,tot),y=fa[x];
recycle(x);tr[y][]=;
pushup(y);pushup(fa[y]);
return;
}
int main(){
int n=read(),m=read();
mx[]=a[]=a[n+]=-INF;
for(int i=;i<=n+;i++)a[i]=read();
for(int i=;i<=n+;i++)id[i]=i;
build(,n+,);
root=(n+)>>;sz=n+;
for(int i=;i<=m;i++){
scanf("%s",s);
if(s[]=='I'){
int k=read(),tot=read();
insert(k,tot);
}
if(s[]=='D'){
int k=read(),tot=read();
del(k,tot);
}
if(s[]=='M'){
if(s[]=='X')printf("%d\n",mx[root]);
else{
int k=read(),tot=read(),c=read();
modify(k,tot,c);
}
}
if(s[]=='R'){
int k=read(),tot=read();
turn(k,tot);
}
if(s[]=='G'){
int k=read(),tot=read();
query(k,tot);
}
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ1500:[NOI2005]维修数列——题解的更多相关文章
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500 1.覆盖标记用INF表示无覆盖标记,要求可能用0覆盖 2.代表空节点的0号节点和首尾的两个虚拟 ...
- splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)
先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- BZOJ1500[NOI2005]维修数列
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- [bzoj1500][NOI2005]维修数列——splay
题目 题解 这道题可以说是数列问题的大BOSS,也算是这一周来学习splay等数据结构的一个总结. 我们一个一个地看这些操作. 对于操作1,我们首先建一棵子树,直接接上原树即可. 对于操作2,我们找到 ...
- BZOJ1500 [NOI2005]维修数列(Splay tree)
[Submit][Status][Discuss] Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 Inp ...
- BZOJ1500: [NOI2005]维修数列[splay ***]
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 12278 Solved: 3880[Submit][Statu ...
随机推荐
- Linux命令非常全
最近都在和Linux打交道,感觉还不错.这也是很多人喜欢linux的原因,比较短小但却功能强大.我将我了解到的命令列举一下,仅供大家参考: 系统信息 arch 显示机器的处理器架构(1) uname ...
- NavRouter
使用方法只需要跟vue-router一样正常使用即可,这里我们新加了一个路由跳转方法nav: router.nav()//参数同router.replace一样. 路由跳转策略 首先说下路由跳转过程, ...
- 180620-mysql之数据库导入导出
文章链接:https://liuyueyi.github.io/hexblog/2018/06/20/180620-mysql之数据库导入导出/ mysql之数据库导入导出 实际工作中,需要做一下数据 ...
- 180608-Git工具之Stash
git stash 暂存 背景: 实际开发过程中,经常可能遇到的一个问题,当你在dev分支上正开发得happy的时候:突然来了个线上bug,得赶紧从release分支上切一个bugfix分支来解决线上 ...
- unittest,selenium——批量,多线程执行多文档用例
之前做过批量执行多.py文件,为了省时也做过单py文件多线程,现在做多py文件用例多线程 # coding:utf-8import unittestimport osimport timeimport ...
- win 下通过dos命令格式化磁盘
该命令可以解决好多问题,比如: 1.u盘作为启动后,如何恢复成正常的u盘 1.win + r ->cmd 进入dos模式 2.输入diskpart后回车,点击确定,进入diskpart命令的交互 ...
- 洛谷P1068 分数线划定:sort结构体排序+贪心
题目描述 世博会志愿者的选拔工作正在 A 市如火如荼的进行.为了选拔最合适的人才,A市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试. 面试分数线根据计划录取人数的150%划定, ...
- javaScript中两个等于号和三个等于号之间的区别
一言以蔽之:==先转换类型再比较,===先判断类型,如果不是同一类型直接为false. ===表示恒等于,比较的两边要绝对的相同 alert(0 == ""); // trueal ...
- Thunder——基于NABCD评价“欢迎来怼”团队作品
基于NABCD N——need需求 对于开设了软件工程课并且正在进行教学活动的老师和同学,除了在写作业时会打开电脑进行操作,平时我们更希望可以通过一些简单方便的方法来查看有关作业的内容,比如查看一下老 ...
- 软件工程-东北师大站-第二次作业psp
1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 本周PSP饼状图
.png)