BZOJ 1500 维修数列【Splay】
注意:1,内存限制,所以需要回收删除的点
2,当前节点的左连续区间和最大值=max(左子树的左连续区间和最大值,左子树的总和+当节点的值+max(右子树的左连续区间和最大值,0));右连续区间和最大值同理
当前节点的区间和最大值=max(左子树的区间和最大值,max(右子树的区间和最大值,max(左子树的右连续区间和最大值,0)+max(右子树的左连续区间和最大值,0)+当前节点的值))
3,pushdown时,应该交换左子树的左连续区间和最大值与左子树的右连续区间和最大值。因为向上更新时这两个值的不同对结果有影响,不能延迟更新。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=;
const int INF=0x7fffffff;
int data[N],fa[N],id,root;
int size[N],sum[N],a[N];
int t[N][],st[N],top;
int mxl[N],mxr[N],mxm[N];
int same[N],flip[N];
void re(int x);
inline void pushup(int x){
int l=t[x][],r=t[x][];
sum[x]=sum[l]+sum[r]+data[x];
size[x]=size[l]+size[r]+;
mxl[x]=max(mxl[l],sum[l]+data[x]+max(mxl[r],));
mxr[x]=max(mxr[r],sum[r]+data[x]+max(mxr[l],));
mxm[x]=max(mxm[l],mxm[r]);
mxm[x]=max(mxm[x],max(mxr[l],)+data[x]+max(mxl[r],));
}
inline void pushdown(int x){
int l=t[x][],r=t[x][];
if(flip[x]){
flip[x]=;
swap(t[x][],t[x][]);
if(l){
flip[l]^=;
swap(mxl[l],mxr[l]);
}
if(r){
flip[r]^=;
swap(mxl[r],mxr[r]);
}
}
if(same[x]!=-INF){
if(l){
same[l]=data[l]=same[x];
sum[l]=same[l]*size[l];
mxl[l]=mxr[l]=mxm[l]=max(data[l],sum[l]);
}
if(r){
same[r]=data[r]=same[x];
sum[r]=same[r]*size[r];
mxl[r]=mxr[r]=mxm[r]=max(data[r],sum[r]);
}
same[x]=-INF;
}
}
void Rotate(int x,int w){
int y=fa[x],z=fa[y];
pushdown(y);
t[y][!w]=t[x][w];
fa[t[x][w]]=y;
fa[x]=z;
t[z][t[z][]==y]=x;
t[x][w]=y;
fa[y]=x;
pushup(y);
}
void Splay(int x,int y){
if(x!=y){
pushdown(x);
while(fa[x]!=y){
if(t[fa[x]][]==x)
Rotate(x,);
else
Rotate(x,);
}
pushup(x);
if(!y)root=x;
} }
void newnode(int &x,int y,int v){
if(top>)
x=st[top--];
else
x=++id;
flip[x]=t[x][]=t[x][]=;
mxl[x]=mxr[x]=mxm[x]=sum[x]=data[x]=v;
same[x]=-INF;
fa[x]=y;
size[x]=;
}
void build(int &x,int y,int l,int r){
if(l<=r){
int mid=(l+r)>>;
newnode(x,y,a[mid]);
build(t[x][],x,l,mid-);
build(t[x][],x,mid+,r);
pushup(x);
}
}
void init(int n){
top=root=id=;
t[][]=t[][]=fa[]=sum[]=size[]=data[]=flip[]=;
same[]=mxl[]=mxr[]=mxm[]=-INF;
newnode(root,,-INF);
newnode(t[][],,-INF);
build(t[][],,,n);
pushup();
pushup();
}
int Select(int k){
pushdown(root);
int x=root;k++;
for(;size[t[x][]]+!=k;){
if(size[t[x][]]+>k)
x=t[x][];
else
k-=size[t[x][]]+,x=t[x][];
pushdown(x);
}
return x;
}
void Insert(int c,int n){
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
int cc=Select(c+);
c=Select(c);
Splay(c,);
Splay(cc,c);
build(t[cc][],cc,,n);
pushup(cc);
pushup(c);
}
void recall(int x){
if(x){
st[++top]=x;
recall(t[x][]);
recall(t[x][]);
}
}
void Delete(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
recall(t[r][]);
t[r][]=;
pushup(r);
pushup(l);
}
void Flip(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
flip[t[r][]]^=;
swap(mxl[t[r][]],mxr[t[r][]]);
}
void Same(int l,int r,int v){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
int x=t[r][];
same[x]=data[x]=v;
sum[x]=data[x]*size[x];
mxl[x]=mxr[x]=mxm[x]=max(v,sum[x]);
pushup(r);
pushup(l);
}
int Sum(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
return sum[t[r][]];
}
int Max(int l,int r){
l=Select(l-),r=Select(r+);
Splay(l,),Splay(r,l);
return mxm[t[r][]];
}
void de(){
for(int i=;i<=id;i++){
printf("%d %d %d %d %d++\n",i,t[i][],t[i][],sum[i],mxm[i]);
}
}
void re(int x){
if(x){
re(t[x][]);
printf("%d ",data[x]);
re(t[x][]);
}
}
int main(){
int n,m,i,p,cnt,v;
char op[];
while(scanf("%d%d",&n,&m)!=EOF){
for(i=;i<=n;i++) scanf("%d",&a[i]);
init(n);
//de();
while(m--){
scanf("%s",op);
if(!strcmp(op,"GET-SUM")){
scanf("%d%d",&p,&cnt);
printf("%d\n",Sum(p,p+cnt-));
}
if(!strcmp(op,"MAX-SUM")){
printf("%d\n",Max(,size[root]-));
}
if(!strcmp(op,"INSERT")){
scanf("%d%d",&p,&cnt);
Insert(p,cnt);
}
if(!strcmp(op,"DELETE")){
scanf("%d%d",&p,&cnt);
Delete(p,p+cnt-);
}
if(!strcmp(op,"MAKE-SAME")){
scanf("%d%d%d",&p,&cnt,&v);
Same(p,p+cnt-,v);
}
if(!strcmp(op,"REVERSE")){
scanf("%d%d",&p,&cnt);
Flip(p,p+cnt-);
}
}
}
return ;
}
/*
9 8 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
*/
BZOJ 1500 维修数列【Splay】的更多相关文章
- [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
历尽艰辛终于A掉了这题QwQ 贴COGS评论区几句话=.= 策爷:"splay/块状链表的自虐题.".深刻理解到如果没有M倾向就不要去写这题了.. -Chenyao2333 记得b ...
- bzoj 1500 维修数列
splay乱搞. 调了两个多小时...这辈子再也不想写splay了... 维护左边最大连续和右边最大连续,维护两个标记,无脑push_down.push_up就行了. 注意最大连续和至少要包含一个数. ...
- bzoj 1500: [NOI2005]维修数列 splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 6556 Solved: 1963[Submit][Status ...
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4229 Solved: 1283[Submit][Status ...
- 【BZOJ-1500】维修数列 Splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 11047 Solved: 3460[Submit][Statu ...
- 【BZOJ1500】[NOI2005]维修数列 Splay
[BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行 ...
- [NOI2005]维修数列 Splay tree 区间反转,修改,求和,求最值
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1500 Description Input 输入文件的第1行包含两个数N和M,N表示初始时数 ...
- 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 ...
随机推荐
- MySQL Plugin 'InnoDB' init function returned error一例
早上上班后,测试说演示环境挂了,维护上去看了下,启动报错了: XXXXXX08:30:47 mysqld_safe Starting mysqld daemon with databases from ...
- html,xhtml和xml
html,xhtml和xml的定义: 1.html即是超文本标记语言(Hyper Text Markup Language),是最早写网页的语言,但是由于时间早,规范不是很好,大小写混写且编码不规范: ...
- [Tips] Useful link ... on going
1. CSS Bootstrap http://getbootstrap.com/ Bootstrap 中文文档 http://getbootstrap.com/2.3.2/ 最全的 Twitter ...
- CSS3属性(二)
<html> <head> <title>css2</title> <style type="text/css"> di ...
- 安卓开发_浅谈OptionsMenus(选项菜单)
Android平台下所提供的菜单大体上可分为三类:选项菜单.上下文菜单和子菜单. 当Activity在前台运行时,如果用户按下手机上的Menu键,此时就会在屏幕低端弹出相应的选项菜单.但这个功能需要开 ...
- OC字符串的一些常用的函数。
)//获取字符串长度 NSUInteger len= str.length; () //通过指定索引返回对应的字符 unichar ch =[str characterAtIndex:]; ()//通 ...
- OC第一讲:类和对象
今天终于开始进行OC的学习了 一.首先讲了NSLog NSLog是oc里面的输出语句,其用法和printf差不多,但是还是有差别的 1,NSLog是自动换行的,不用像printf那样还需要加'\n': ...
- VIP - virtual IP address
virtual IP address (虚拟 IP 地址)1.是集群的ip地址,一个vip对应多个机器2.与群集关联的唯一 IP 地址 see wiki: A virtual IP address ( ...
- [QualityCenter]设置工作流脚本-设置不同字段值关联不同列表
需求:当选择A字段某个值时,设置B字段的列表值根据A字段的值来判断读取不同的列表值,如当运行省份的值已更改, 运行地区的选择列表将更改. 在脚本编辑器新建一个函数UserFuntion_Bug_Pro ...
- ubuntu wireshark finish
http://blog.csdn.net/cumirror/article/details/4694283 安装编译工具: $sudo apt-get install build-essential ...