维修队列(bzoj 1500)
Description

Input
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
Sample Input
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
10
1
10
HINT

/*
都是splay的一下基本操作,只是看得懂,但自己写不出来。
*/
#include<cstdio>
#include<iostream>
#include<queue>
#define N 500010
#define inf 1000000000
using namespace std;
int a[N],id[N],fa[N],c[N][];
int v[N],size[N],sum[N],mx[N],lx[N],rx[N],n,m,rt,sz;
int tag[N],rev[N];
queue<int> q; void pushup(int k){
int l=c[k][],r=c[k][];
mx[k]=max(max(mx[l],mx[r]),rx[l]+lx[r]+v[k]);
lx[k]=max(lx[l],sum[l]+lx[r]+v[k]);
rx[k]=max(rx[r],sum[r]+rx[l]+v[k]);
sum[k]=sum[l]+sum[r]+v[k];
size[k]=size[l]+size[r]+;
} void pushdown(int k){
int l=c[k][],r=c[k][];
if(tag[k]){
tag[k]=rev[k]=;
if(l) tag[l]=,v[l]=v[k],sum[l]=v[k]*size[l];
if(r) tag[r]=,v[r]=v[k],sum[r]=v[k]*size[r];
if(v[k]>){
if(l) mx[l]=lx[l]=rx[l]=sum[l];
if(r) mx[r]=lx[r]=rx[r]=sum[r];
}
else {
if(l) mx[l]=v[l],lx[l]=rx[l]=;
if(r) mx[r]=v[r],lx[r]=rx[r]=;
}
}
if(rev[k]){
rev[l]^=;rev[r]^=;rev[k]^=;
swap(lx[l],rx[l]);swap(lx[r],rx[r]);
swap(c[l][],c[l][]);swap(c[r][],c[r][]);
}
} void rotate(int x,int &k){
int y=fa[x],z=fa[y],l,r;
if(c[y][]==x) l=;else l=;r=l^;
if(y==k) k=x;
else {
if(c[z][]==y) c[z][]=x;
else c[z][]=x;
}
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
} void splay(int x,int &k){
while(x!=k){
int y=fa[x],z=fa[y];
if(y!=k){
if(c[z][]==y^c[y][]==x) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
} int find(int k,int rk){
pushdown(k);
if(size[c[k][]]+==rk) return k;
else if(size[c[k][]]>=rk) return find(c[k][],rk);
else find(c[k][],rk-size[c[k][]]-);
} int split(int k,int tot){
int x=find(rt,k),y=find(rt,k+tot+);
splay(x,rt);splay(y,c[x][]);
return c[y][];
} void build(int l,int r,int f){
if(l>r) return;
int mid=l+r>>,last=id[f],now=id[mid];
if(l==r){
sum[now]=mx[now]=a[l];size[now]=;
tag[now]=rev[now]=;
lx[now]=rx[now]=max(,a[l]);
}
else build(l,mid-,mid),build(mid+,r,mid);
v[now]=a[mid];fa[now]=last;c[last][mid>=f]=now;
pushup(now);
} void insert(int k,int tot){
for(int i=;i<=tot;i++){
if(!q.empty()) id[i]=q.front(),q.pop();
else id[i]=++sz;
scanf("%d",&a[i]);
}
build(,tot,);int z=id[(+tot)>>];
int x=find(rt,k+),y=find(rt,k+);
splay(x,rt);splay(y,c[x][]);
c[y][]=z;fa[z]=y;
pushup(y);pushup(x);
} void rec(int k){
if(!k) return;
int l=c[k][],r=c[k][];
rec(l);rec(r);q.push(k);
fa[k]=c[k][]=c[k][]=tag[k]=rev[k]=;
} void del(int k,int tot){
int x=split(k,tot),y=fa[x];
rec(x);c[y][]=;
pushup(y);pushup(fa[y]);
} void modify(int k,int tot,int c){
int x=split(k,tot),y=fa[x];
v[x]=c;tag[x]=;sum[x]=v[x]*size[x];
mx[x]=max(v[x],sum[x]);
lx[x]=rx[x]=max(,sum[x]);
pushup(y);pushup(fa[y]);
} void rever(int k,int tot){
int x=split(k,tot),y=fa[x];
rev[x]^=;
swap(lx[x],rx[x]);
swap(c[x][],c[x][]);
pushup(y);pushup(fa[y]);
} int querysum(int k,int tot){
int x=split(k,tot);
return sum[x];
} int main(){
scanf("%d%d",&n,&m);mx[]=a[]=a[n+]=-inf;
for(int i=;i<=n;i++) scanf("%d",&a[i+]);
for(int i=;i<=n+;i++) id[i]=i;
build(,n+,);
rt=(n+)>>;sz=n+;
char ch[];int k,tot,c;
for(int i=;i<=m;i++){
scanf("%s",ch);
if(ch[]!='M'||ch[]!='X') scanf("%d%d",&k,&tot);
if(ch[]=='I') insert(k,tot);
if(ch[]=='D') del(k,tot);
if(ch[]=='R') rever(k,tot);
if(ch[]=='G') printf("%d\n",querysum(k,tot));
if(ch[]=='M'){
if(ch[]=='X') printf("%d\n",mx[rt]);
else scanf("%d",&c),modify(k,tot,c);
}
}
return ;
}
维修队列(bzoj 1500)的更多相关文章
- [BZOJ 1500] [NOI2005] 维修数列
题目链接:BZOJ - 1500 题目分析 我要先说一下,这道题我写了一晚上,然后Debug了一整个白天..........再一次被自己的蒟蒻程度震惊= = 这道题是传说中的Splay维护数列的Bos ...
- [BZOJ 1500] 维护序列
Link: BZOJ 1500 传送门 Solution: 可能平衡树维护序列的所有操作都在这了吧…… 对序列的维护$fhq treap$和$Splay$都能做 有几个注意点: 1.维护序列时始终记得 ...
- bzoj 1500: [NOI2005]维修数列 splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 6556 Solved: 1963[Submit][Status ...
- [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
历尽艰辛终于A掉了这题QwQ 贴COGS评论区几句话=.= 策爷:"splay/块状链表的自虐题.".深刻理解到如果没有M倾向就不要去写这题了.. -Chenyao2333 记得b ...
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4229 Solved: 1283[Submit][Status ...
- BZOJ 1500/Luogu 2042 - 维修数列 - [NOI2005][Splay]
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1500 题目链接:https://www.luogu.org/problemnew/sho ...
- bzoj 1500 维修数列
splay乱搞. 调了两个多小时...这辈子再也不想写splay了... 维护左边最大连续和右边最大连续,维护两个标记,无脑push_down.push_up就行了. 注意最大连续和至少要包含一个数. ...
- BZOJ 1500 维修数列【Splay】
注意:1,内存限制,所以需要回收删除的点 2,当前节点的左连续区间和最大值=max(左子树的左连续区间和最大值,左子树的总和+当节点的值+max(右子树的左连续区间和最大值,0)):右连续区间和最大值 ...
- bzoj 1500 维修序列
Written with StackEdit. Description 请写一个程序,要求维护一个数列,支持以下 \(6\) 种操作: 请注意,格式栏 中的下划线' _ '表示实际输入文件中的空格 I ...
随机推荐
- 1898 ERROR nova.compute.manager
2018-06-10 21:03:54.045 1898 ERROR nova.compute.manager [instance: 15a6c26f-b8af-4a3e-a3df-8552c16e0 ...
- IOS音频视频
视频播放 MediaPlayer.framework MPMoviePlayerViewController VS MPMoviePlayerController MPMoviePlayerViewC ...
- 历史管理 onhashchange
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- k8s学习目录
目录 K8S基础部分 基础部分 5 秒创建 k8s 集群[转] k8s 核心功能[转] k8s 重要概念[转] 部署 k8s Cluster(上)[转] 部署 k8s Cluster(下)[转] Ku ...
- python 实例方法,类方法,静态方法,普通函数
python中有实例方法,类方法,静态方法,普通函数 类方法需要@ classmethod 修饰并且有个隐藏参数 cls,实例方法必须有个参数 self, 静态方法必须有 @staticmethod修 ...
- 数据库_8_SQL基本操作——数据操作
SQL基本操作——数据操作 一.新增数据(两种方案) 方案1: 给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致,凡是非数值数据,都需要使用引号(建议是 ...
- Sniper OJ部分writeup
0x00 shellcode pwn 因为题目直接有源码,我就不拖进IDA了,直接看代码 这是一个典型的栈溢出,我们只需要构造shellcode获得/bin/sh权限就可以得到flag.下面是所用脚本 ...
- 五分钟入门 Dingo API
基于 https://laravel-china.org/doc... 文档更简洁的描述Dingo,直戳重点,注重实践 Django-Book 概述 Dingo API帮助您轻松快速地构建自己的API ...
- 【http】【转发】HTTP访问控制(CORS)
当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求. 比如,站点 http://domain-a.com 的某 HTML 页面通过 <img ...
- day23 03 组合的例子
day23 03 组合的例子 一.用到组合的方式,编写一个圆环,并能够计算出它的周长和面积 from math import pi # 从内置函数里面导入pi # 先定义一个圆类 class Circ ...