【BZOJ1500】[NOI2005]维修数列 Splay

【BZOJ1500】[NOI2005]维修数列

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

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

Sample Output

-1
10
1
10

HINT

题解:裸的Splay,只不过全是细节,我还是不够细啊~

*要开滚动数组记录有哪些空余的位置,防止MLE(但实测600000的数组就行)

*INSERT:直接一个一个往里加就行,加成一条链也无所谓,不会TLE

*DELETE:因为要释放空间,所以必须一个一个删除,递归即可

*MAKE_SAME:没啥说的
*REVERSE:最好是先修改,再给儿子打标记(也就是说标记只对儿子起作用),这样比较清晰

*GET_SUM:没啥说的
*MAX_SUM:巨恶心的pushup和pushdown,看代码就知道了

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
struct point
{int ch[2],fa,siz,tag,v,sv,sm,ls,rs,re;
}s[600010];
int n,m,root;
int num[500010];
char str[20];
queue<int> q;
void pushdown(int x)
{if(s[x].re){swap(s[s[x].ch[0]].ch[0],s[s[x].ch[0]].ch[1]);swap(s[s[x].ch[1]].ch[0],s[s[x].ch[1]].ch[1]);swap(s[s[x].ch[0]].ls,s[s[x].ch[0]].rs);swap(s[s[x].ch[1]].ls,s[s[x].ch[1]].rs);if(s[x].ch[0])	s[s[x].ch[0]].re^=1;if(s[x].ch[1])	s[s[x].ch[1]].re^=1;s[x].re=0;}if(s[x].tag!=1<<30){if(s[x].ch[0]){s[s[x].ch[0]].v=s[s[x].ch[0]].tag=s[x].tag;s[s[x].ch[0]].sv=s[x].tag*s[s[x].ch[0]].siz;s[s[x].ch[0]].ls=s[s[x].ch[0]].rs=max(s[s[x].ch[0]].sv,0);s[s[x].ch[0]].sm=max(s[s[x].ch[0]].sv,s[x].tag);}if(s[x].ch[1]){s[s[x].ch[1]].v=s[s[x].ch[1]].tag=s[x].tag;s[s[x].ch[1]].sv=s[x].tag*s[s[x].ch[1]].siz;s[s[x].ch[1]].ls=s[s[x].ch[1]].rs=max(s[s[x].ch[1]].sv,0);s[s[x].ch[1]].sm=max(s[s[x].ch[1]].sv,s[x].tag);}s[x].tag=1<<30;}
}
void pushup(int x)
{s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;s[x].ls=max(s[s[x].ch[0]].ls,s[s[x].ch[0]].sv+s[x].v+s[s[x].ch[1]].ls);s[x].rs=max(s[s[x].ch[1]].rs,s[s[x].ch[1]].sv+s[x].v+s[s[x].ch[0]].rs);s[x].sm=max(s[s[x].ch[0]].rs+s[x].v+s[s[x].ch[1]].ls,max(s[s[x].ch[0]].sm,s[s[x].ch[1]].sm));s[x].sv=s[s[x].ch[0]].sv+s[x].v+s[s[x].ch[1]].sv;
}
int readin()
{int ret=0,f=1;	char gc=getchar();while(gc<'0'||gc>'9'){if(gc=='-')f=-f;	gc=getchar();}while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();return ret*f;
}
int rotate(int x,int &k)
{int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);if(z)	s[z].ch[y==s[z].ch[1]]=x;if(y==k)	k=x;s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y;s[x].ch[d^1]=y;pushup(y),pushup(x);
}
void splay(int x,int &k)
{while(x!=k){int y=s[x].fa,z=s[y].fa;if(y!=k){if((x==s[y].ch[1])^(y==s[z].ch[1]))	rotate(x,k);else	rotate(y,k);}rotate(x,k);}
}
void build(int l,int r,int last)
{if(l>r)	return ;int mid=l+r>>1;s[mid].fa=last,s[last].ch[mid>last]=mid;s[mid].v=num[mid];s[mid].tag=1<<30;build(l,mid-1,mid),build(mid+1,r,mid);pushup(mid);
}
int find(int x,int y)
{pushdown(x);if(s[s[x].ch[0]].siz+1==y)	return x;if(y<=s[s[x].ch[0]].siz)	return find(s[x].ch[0],y);return find(s[x].ch[1],y-s[s[x].ch[0]].siz-1);
}
void del(int &x)
{if(!x) return;q.push(x);del(s[x].ch[0]),del(s[x].ch[1]);x=0;
}
int main()
{n=readin(),m=readin();int i,j,a,b,c,t,u;s[0].sm=num[1]=num[n+2]=-1<<30;for(i=1;i<=n;i++)	num[i+1]=readin();n+=2,root=(n+1)/2;build(1,root-1,root),build(root+1,n,root);s[root].v=num[root];s[root].tag=1<<30;pushup(root);for(i=n+1;i<=600000;i++)	q.push(i);for(i=1;i<=m;i++){scanf("%s",str);switch(str[2]){case 'S':{a=readin()+1,b=readin();splay(find(root,a+1),root),splay(find(root,a),s[root].ch[0]);t=s[root].ch[0];for(j=1;j<=b;j++){c=readin();u=q.front(),q.pop();s[u].v=c;s[t].ch[1]=u,s[u].fa=t;s[u].re=0,s[u].tag=1<<30;t=u;}while(t!=root){pushup(t);t=s[t].fa;}break;}case 'L':{a=readin()+1,b=readin();splay(find(root,a-1),root),splay(find(root,a+b),s[root].ch[1]);del(s[s[root].ch[1]].ch[0]);pushup(s[root].ch[1]);break;}case 'K':{a=readin()+1,b=readin();splay(find(root,a-1),root),splay(find(root,a+b),s[root].ch[1]);c=s[s[root].ch[1]].ch[0];s[c].v=s[c].tag=readin();s[c].re=0;s[c].sv=s[c].siz*s[c].v;s[c].ls=s[c].rs=max(s[c].sv,0);s[c].sm=max(s[c].sv,s[c].v);break;}case 'V':{a=readin()+1,b=readin();splay(find(root,a-1),root),splay(find(root,a+b),s[root].ch[1]);c=s[s[root].ch[1]].ch[0];swap(s[c].ch[0],s[c].ch[1]);swap(s[c].ls,s[c].rs);s[c].re=1;break;}case 'T':{a=readin()+1,b=readin();splay(find(root,a-1),root),splay(find(root,a+b),s[root].ch[1]);printf("%d\n",s[s[s[root].ch[1]].ch[0]].sv);break;}case 'X':{printf("%d\n",s[root].sm);break;}}}return 0;
}

 

转载于:https://www.cnblogs.com/CQzhangyu/p/6440275.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)

每个节点继承父节点的树&#xff0c;则答案为query(root[x]root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> using namespace std; const int maxn1…

图文详解YUV420数据格式

YUV格式有两大类&#xff1a;planar和packed。 对于planar的YUV格式&#xff0c;先连续存储所有像素点的Y&#xff0c;紧接着存储所有像素点的U&#xff0c;随后是所有像素点的V。 对于packed的YUV格式&#xff0c;每个像素点的Y,U,V是连续交*存储的。 YUV&#xff0c;分为三个…

USB通信接口介绍

1. 概述 Usb Universal Serial Bus全称通用串行总线&#xff0c;是一种支持热插拔的高速串行传输总线&#xff0c;使用差分信号来传输数据。 USB设备可以直接和host通信&#xff0c;或者通过hub和host通信。一个USB系统中仅有一个USB主机&#xff0c;设备包括功能设备和hub&…

HDCVI——一种创新性的高清视频传输方案

什么是HDCVI 2012年11月&#xff0c;大华技术股份有限公司发布了具有自主知识产权的同轴高清传输接口技术HDCVI。HDCVI技术是一种基于已有SYV75-3或SYV75-5同轴电缆的高清视频传输方法&#xff0c;能够在低成本和较低质量的同轴电缆上实现超长距离高清视频信号的可靠传输。相比…

智能机器人品牌简介

随着科技的发展&#xff0c;硬件的计算速度和大数据支撑&#xff0c;越来越多的智能化设备和产品出现在我们的面前&#xff0c;为我们的生活带来更多便利。其中包括智能机器人&#xff0c;这种产品是有自己的“大脑”&#xff0c;可以接收人为指令&#xff0c;为人服务&#xf…

诞生之日 随笔

今天我诞生了&#xff0c;祝自己诞生日happy&#xff0c;happy&#xff0c;happy&#xff01; 转载于:https://www.cnblogs.com/xiaohuihui-/p/7594406.html

智能音箱 之 麦克风参数介绍

1. 定义 麦克风&#xff0c;学名为传声器&#xff0c;是将声音信号转换为电信号的能量转换器件&#xff1b;声—电转换。 与扬声器正好相反&#xff08;电—声转换&#xff09;&#xff0c;构成电声设备的两个终端&#xff0c;俗称咪头&#xff0c;麦克等。 是电声系统的入口&a…

利用django框架,手把手教你搭建数据可视化系统(一)

如何使用django去构建数据可视化的 web,可视化的结果可以呈现在web上。 使用django的MTV模型搭建网站 基础铺垫—MTV模型 Created with Raphal 2.1.0Request服务器&#xff08;Djangoweb&#xff09;Response首先&#xff0c;要搞清楚我们去访问服务器&#xff0c;服务器返回信…

智能音箱 之 扬声器喇叭介绍

在全双工语音交互的系统中&#xff0c;功放的质量是非常重要的&#xff0c;因为AEC回声消除对信号失真 是非常敏感的。音频通路的整体谐波失真需要控制在5%以内。 对于整个系统的谐波失真来说&#xff0c;扬声器是最关键的因素&#xff0c;其次是功放&#xff0c;麦克风的很小…

UML学习——类图(三)

1.类图 UML类图是用来描述类、接口、协作及它们之间的关系的图。用来显示系统中各个类的静态结构。 2.类图的组成元素 类图由以下六种元素组成&#xff1a;类&#xff0c;接口&#xff0c;泛化关系&#xff0c;关联关系&#xff0c;依赖关系&#xff0c;实现关系。 3.类图的绘制…

传锤子科技解散成都分公司 才搬迁一年罗永浩就顶不住了

雷帝网 乐天 10月16日报道今日有网友爆料&#xff0c;锤子科技解散成都分公司。有网友指出&#xff0c;爆料的人是锤子科技早期员工王前闯。网友爆料锤子成都研发中心解散网友爆料锤子成都研发中心解散2016年&#xff0c;锤子科技亏损4亿元&#xff0c;一直徘徊在破产的边缘&am…

Maven and Nexus2

2019独角兽企业重金招聘Python工程师标准>>> Maven and Nexus2 Maven是什么&#xff1f; 构建工具&#xff1a; 通过简单的命令&#xff0c;能够完成清理、编译、测试、打包、部署等一系列过程。同时&#xff0c;不得不提的是&#xff0c;Maven是跨平台的&#xff0…

Linux kernel的中断子系统之(九):tasklet

返回目录&#xff1a;《ARM-Linux中断系统》。 总结&#xff1a; 二介绍了tasklet存在的意义。 三介绍了通过tasklet_struct来抽想一个tasklet&#xff0c;每个CPU维护一个tasklet链表tasklet_vec/tasklet_hi_vec&#xff0c;然后介绍了如何定一个一个tasklet(静态/动态)&#…

智能音箱 之 功放介绍

基本分类 功率放大器分甲类功放&#xff08;A 类&#xff09;&#xff0c;乙类&#xff08;B 类&#xff09;&#xff0c;甲乙类&#xff08;AB 类&#xff09;和丁类&#xff08;D 类&#xff09;&#xff1b; A 类 指在信号的整个周期内&#xff0c;放大器的任何功率输出…

create_workqueue和create_singlethread_workqueue【转】

本文转载自&#xff1a;http://bgutech.blog.163.com/blog/static/18261124320116181119889/ 1. 什么是workqueueLinux中的Workqueue机制就是为了简化内核线程的创建。通过调用workqueue的接口就能创建内核线程。并且可以根据当前系统CPU的个数创建线程的数量&#xff0c;使得线…

vue学习之路.02

2019独角兽企业重金招聘Python工程师标准>>> 第一个vue项目 1.创建 vue init webpack app01 2.安装依赖 cd app01 npm install 3.构建 npm run dev 启动本机的8080端口 或 …

解析电子墨水屏技术(工作原理与LCD的区别)

阅读电子书早已成为大家生活中一部分&#xff0c;方便轻巧的电子版书籍更便于携带&#xff0c;而电子阅读器也不仅仅局限于电脑、手机等传统设备&#xff0c;新兴的电子书阅读器渐渐为我们所接受。E-ink电子墨水技术就是现在最著名的产品之一&#xff0c;他的出现让电子书阅读器…

入门视频采集与处理(BT656简介) 转

凡是做模拟信号采集的&#xff0c;很少不涉及BT.656标准的&#xff0c;因为常见的模拟视频信号采集芯片都支持输出BT.656的数字信号&#xff0c;那么&#xff0c;BT.656到底是何种格式呢&#xff1f;本文将主要介绍 标准的 8bit BT656&#xff08;4:2:2&#xff09;YCbCr SDTV&…

眼图(Eye Diagram)与数字信号测试

问题: 什么是眼图&#xff1f;它用在什么场合&#xff1f;反映了波形的什么信息&#xff1f;NI相应的解决方案是怎样的&#xff1f; 解答: 眼图&#xff08;Eye Diagram&#xff09;可以显示出数字信号的传输质量&#xff0c;经常用于需要对电子设备、芯片中串行数字信号或者…