P1110 [ZJOI2007]报表统计
题目描述
Q的妈妈是一个出纳,经常需要做一些统计报表的工作。今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一。
经过仔细观察,小Q发现统计一张报表实际上是维护一个非负整数数列,并且进行一些查询操作。
在最开始的时候,有一个长度为N的整数序列,并且有以下三种操作:
INSERT i k:在原数列的第i个元素后面添加一个新元素k;如果原数列的第i个元素已经添加了若干元素,则添加在这些元素的最后(见下面的例子)MIN_GAP:查询相邻两个元素的之间差值(绝对值)的最小值MIN_SORT_GAP:查询所有元素中最接近的两个元素的差值(绝对值)
例如一开始的序列为5, 3, 1。
执行操作INSERT 2 9将得到:5, 3, 9, 1,此时MIN_GAP为22,MIN_SORT_GAP为22。
再执行操作INSERT 2 6将得到:5, 3, 9, 6, 1
注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。
于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
输入输出格式
输入格式:
第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。
第二行为N个整数,为初始序列。
接下来的M行每行一个操作,即INSERT i k,MIN_GAP,MIN_SORT_GAP 中的一种(无多余空格或者空行)。
输出格式:
对于每一个MIN_GAP和MIN_SORT_GAP命令,输出一行答案即可。
输入输出样例
3 5
5 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP
2
2
1
说明
对于30%的数据,N ≤ 1000 ,M ≤ 5000
对于100%的数据,N ,M ≤500000
对于所有的数据,序列内的整数不超过5×108。
时限2s
Solution:
本题splay+堆(好水啊,乱打的代码都能AC~)。
分析题目:
操作1,加入一个数,只会改变相邻的关系,所以数组模拟随便乱搞维护下相邻关系。
操作2,加入一个数,改变的是两对相邻的差值,所以可以直接用带修改的堆去维护(pbds大法好!)。
操作3,由于是维护全局最小值,那么只需要在加入数时,在其插入二叉搜索树的遍历过程中,与访问过的节点更新下答案,当然为了保证树的平衡,选用平衡树写写就行了。
代码:
/*Code by 520 -- 9.17*/
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
#define son(x) (x==ch[fa[x]][1])
using namespace std;
using namespace __gnu_pbds;
const int N=;
int n,m,a[N<<][],tot,val[N<<];
int root,ch[N][],fa[N],cnt,date[N];
int minn=0x7fffffff;
struct node{
int ls,rs,val;
bool operator < (const node &a) const {return val>a.val;}
};
typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap;
heap q;
heap::point_iterator id[N]; int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-') x=getchar();
if(x=='-') x=getchar(),f=;
while(x>=''&&x<='') a=(a<<)+(a<<)+(x^),x=getchar();
return f?-a:a;
} il void rotate(int x){
int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
z?ch[z][c]=x:root=x; fa[x]=z;
if(a) fa[a]=y; ch[y][b]=a;
ch[x][!b]=y,fa[y]=x;
} il void splay(int x,int i){
while(fa[x]!=i){
RE int y=fa[x],z=fa[y];
if(z==i) rotate(x);
else {
if(son(x)==son(y)) rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
} void insert(int &rt,int x){
if(!rt) {rt=++cnt,date[cnt]=x;return;}
if(date[rt]==x) {minn=;return;}
if(x<date[rt])
insert(ch[rt][],x),fa[ch[rt][]]=rt,minn=min(minn,abs(date[rt]-x));
else
insert(ch[rt][],x),fa[ch[rt][]]=rt,minn=min(minn,abs(date[rt]-x));
} int main(){
int pos,x; char s[];
n=gi(),m=gi(),tot=n;
For(i,,n) {
val[i]=gi(),insert(root,val[i]),splay(cnt,);
if(i!=) a[i][]=i;
if(i!=n) a[i][]=i;
}
For(i,,n) id[i]=q.push(node{i,i+,abs(val[i]-val[i-])});
while(m--){
scanf("%s",s);
if(s[]=='I') {
pos=gi(),val[++tot]=gi(),insert(root,val[tot]),splay(cnt,);
int tp=a[pos][];
id[tot]=q.push(node{tot,tp,abs(val[tp]-val[tot])});
if(pos!=n) q.modify(id[pos+],node{pos+,tot,abs(val[pos+]-val[tot])});
a[pos+][]=tot,a[pos][]=tot;
}
else if(strlen(s)==) printf("%d\n",q.top().val);
else printf("%d\n",minn);
}
return ;
}
P1110 [ZJOI2007]报表统计的更多相关文章
- 洛谷 P1110 [ZJOI2007]报表统计 解题报告
P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...
- P1110 [ZJOI2007]报表统计 (multiset)
[题目链接] https://www.luogu.org/problemnew/show/P1110 有以下三种操作: INSERT i k:在原数列的第i个元素后面添加一个新元素k:如果原数列的第i ...
- 2018.11.09 洛谷P1110 [ZJOI2007]报表统计(multiset)
传送门 sb题. 直接用两个multisetmultisetmultiset维护相邻两个数的差值和所有数的前驱后继. 插入一个数的时候更新一下就行了. 代码: #include<bits/std ...
- Luogu P1110 [ZJOI2007]报表统计 multiset
沿用了学长的$multiset$ 然后这道题可以看到我的程序中有两行注释,它在我看来和他们下面的代码没区别,但是我们发现,C++会先调用后面的参数,所以$--it$会被先执行 ... ... ... ...
- bzoj1058: [ZJOI2007]报表统计
set.操作:insert(u,v)在u后面插入v,若u后面已插入过,在插入过的后面插入.mingap求出序列两两之间差值的最小值.minsortgap求出排序后的序列两两之间的最小值.用multis ...
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
- [补档][ZJOI2007] 报表统计
[ZJOI2007] 报表统计 题目 传送门 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观察,小Q发现统计一 ...
- BZOJ_1058_[ZJOI2007]报表统计_STL
BZOJ_1058_[ZJOI2007]报表统计_STL Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼 ...
- bzoj 1058: [ZJOI2007]报表统计 (Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...
随机推荐
- Sqlite数据库sqlite3命令小记
SQLite库包含一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令.本文档提供一个样使用sqlite3的简要说明. 开始 启动sqlite3程序,仅仅需 ...
- 没听说过这些,就不要说你懂并发了,two。
引言 为了更加形象的描述并发的基础知识,因此本文LZ采用了园子里一度大火的标题形式——“没听说过XXXX,就不要说你XXXX了”.希望能够给猿友们一个醒目的警醒,借此来普及并发的基础知识,也讨论一下这 ...
- 大神教你零基础学PS,30堂课从入门到精通
ps视频教程,ps自学视频教程.ps免费视频教程下载,大神教你零基础学PS教程视频内容较大,分为俩部分: 大神教你零基础学PS--30堂课从入门到精通第一部分:百度网盘,https://pan.bai ...
- 图片转换成word 公式
1 下载安装mathpix, 利用该软件将图片转换成LaTeX公式 2 参考此帖,将LaTeX公式转换成word公式 https://www.douban.com/note/648629593/ ht ...
- hdu1232畅通工程(并查集,简单题)
传送门 最少好要修多少条路太能使全部城镇连通.只要用并查集算可以连通的城市的组数,修的路就是组数减1 #include<bits/stdc++.h> using namespace std ...
- kafka consumer demo
kafka消费者demo pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmln ...
- IPC_Binder_java_1
title: IPC_Binder_java_1 date: 2017-01-03 21:30:55 tags: [IPC,Binder] categories: [Mobile,Android] - ...
- ssh软件及命令的使用
常用软件安装及使用目录 第1章 ssh常用用法小结 1.1 连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以 ...
- Python基础系列讲解——继承派生和组合的概念剖析
Python作为一门面向对象的语言,它的面向对象体系中主要存在这么两种关系,一个是“类”和“实例”的关系,另一个是“父类”和“子类”的关系. 所谓“类”是从一堆对象中以抽象的方式把相同的特征归类得到的 ...
- 信息安全系统设计基础_exp1
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级:1353 姓名:吴子怡.郑伟 学号:20135313.20135322 指导教师: 娄嘉鹏 实验 ...