维修队列(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 ...
随机推荐
- PBI DAX 中GroupBy
平时工作中经常会遇到Group By 的情形,用sql 写group by 很容易,在PBI中可以这样写: SUMMARIZE(表名,GroupBy Key ,"聚合列命名",DI ...
- uiviewcontroller 键盘不遮挡信息
//添加监听事件 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow: ...
- org.springframework.beans.factory.BeanCreationException: Could not autowire
由于我在项目中引用了如下代码,增加了 @Configurationpublic class Connection { public @Bean HttpClientConfig httpClie ...
- Codeforces Round #277.5 (Div. 2)-C. Given Length and Sum of Digits...
http://codeforces.com/problemset/problem/489/C C. Given Length and Sum of Digits... time limit per t ...
- Codeforces Round #271 (Div. 2)-B. Worms
http://codeforces.com/problemset/problem/474/B B. Worms time limit per test 1 second memory limit pe ...
- idea下使用码云插件进行git提交
1)下载插件 file->setting->plugins->右侧搜索gitee->安装->重启ide 2)配置版本控制 file->setting->Ver ...
- Swift在1.2版本的变化
从Xcode 6.3 Beta Release Notes看出,Xcode 6.3 Beta包含了很多颇为值得开发者期待的改变,共计50多处改动,同时修改了Objective-C的语法,足见苹果对Sw ...
- java面试宝典第四弹
动态代理 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,“委托者” ...
- 常用JavaScript正则表达式整理
在表单验证中,正则表达式书写起来特别繁琐,本文整理了15个常用的JavaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IP ...
- mysql查询数据包太大:max_allowed_packet
查询大小: show variables like '%max_allowed_packet%'; 修改大小: set global max_allowed_packet = 1024 * 1024 ...