1058: [ZJOI2007]报表统计 - BZOJ
Description
小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为2,MIN_SORT_GAP为2。 再执行操作INSERT 2 6将得到: 5 3 9 6 1 注意这个时候原序列的第2个元素后面已经添加了一个9,此时添加的6应加在9的后面。这个时候MIN_GAP为2,MIN_SORT_GAP为1。于是小Q写了一个程序,使得程序可以自动完成这些操作,但是他发现对于一些大的报表他的程序运行得很慢,你能帮助他改进程序么?
Input
第一行包含两个整数N,M,分别表示原数列的长度以及操作的次数。第二行为N个整数,为初始序列。接下来的M行每行一个操作,即“INSERT i k”,“MIN_GAP”,“MIN_SORT_GAP”中的一种(无多余空格或者空行)。
Output
对于每一个“MIN_GAP”和“MIN_SORT_GAP”命令,输出一行答案即可。
Sample Input
3 5
5 3 1
INSERT 2 9
MIN_SORT_GAP
INSERT 2 6
MIN_GAP
MIN_SORT_GAP
Sample Output
2
2
1
HINT
对于30%的数据,N ≤ 1000 , M ≤ 5000 对于100%的数据,N , M ≤500000 对于所有的数据,序列内的整数不超过5*108。
囧,又是splay,又被卡常数了,每次基本上都是对着数据调才调过的
我用两颗splay树,一个存所有的数(每次查前驱和后继更新答案),一个存所有的差值
当minsortgap为0时就不用再更新它了,还有,因为相邻的差值有一部分是不会被删除的,所以用min记录这些值中最小的值,大于等于min的差值就不用管它了(既不用删除,也不用插入)
搞了这么久终于过了(不过很慢,1300ms+)
const
maxn=;
type
node=record
son:array[..]of longint;
x,count,fa:longint;
end;
var
tree:array[..maxn*]of node;
a,b:array[..maxn]of longint;
n,m,mingap,minsortgap,min,tot,root1,root2:longint;
flag:boolean; procedure down(var x:longint;y:longint);
begin
if x>y then x:=y;
end; procedure rotate(x,w:longint;var root:longint);
var
y:longint;
begin
y:=tree[x].fa;
tree[y].son[w]:=tree[x].son[w xor ];
if tree[x].son[w xor ]<> then tree[tree[x].son[w xor ]].fa:=y;
tree[x].son[w xor ]:=y;
if root=y then root:=x
else
if tree[tree[y].fa].son[]=y then tree[tree[y].fa].son[]:=x
else tree[tree[y].fa].son[]:=x;
tree[x].fa:=tree[y].fa;
tree[y].fa:=x;
end; procedure splay(x,z:longint;var root:longint);
var
y:longint;
begin
while tree[x].fa<>z do
begin
y:=tree[x].fa;
if tree[y].fa=z then
if tree[y].son[]=x then rotate(x,,root)
else rotate(x,,root)
else
if tree[tree[y].fa].son[]=y then
if tree[y].son[]=x then
begin
rotate(y,,root);
rotate(x,,root);
end
else
begin
rotate(x,,root);
rotate(x,,root);
end
else
if tree[y].son[]=x then
begin
rotate(x,,root);
rotate(x,,root);
end
else
begin
rotate(y,,root);
rotate(x,,root);
end;
end;
end; function pre(now:longint):longint;
begin
now:=tree[now].son[];
while tree[now].son[]<> do
now:=tree[now].son[];
exit(now);
end; function succ(now:longint):longint;
begin
now:=tree[now].son[];
while tree[now].son[]<> do
now:=tree[now].son[];
exit(now);
end; procedure delete(x:longint);
var
now,l,r:longint;
begin
now:=root2;
while true do
begin
if now= then exit;
if tree[now].x=x then break;
if tree[now].x>x then now:=tree[now].son[]
else now:=tree[now].son[];
end;
splay(now,,root2);
if tree[root2].count> then dec(tree[root2].count)
else
begin
if (tree[root2].son[]=) or (tree[root2].son[]=) then
begin
if tree[root2].son[]<> then mingap:=tree[succ(root2)].x;
root2:=tree[root2].son[]+tree[root2].son[];
tree[root2].fa:=;
exit;
end;
l:=pre(root2);
r:=succ(root2);
splay(l,,root2);
splay(r,l,root2);
tree[r].son[]:=;
end;
end; procedure insert(x:longint;var root:longint);
var
now:longint;
begin
now:=root;
if root= then
begin
inc(tot);
root:=tot;
tree[tot].x:=x;
tree[tot].count:=;
if root=root2 then down(mingap,x);
exit;
end;
while true do
begin
if tree[now].x=x then
if root=root1 then
begin
minsortgap:=;
flag:=true;
exit;
end
else
begin
inc(tree[now].count);
exit;
end;
if tree[now].x>x then
if tree[now].son[]= then break
else now:=tree[now].son[]
else
if tree[now].son[]= then break
else now:=tree[now].son[];
end;
inc(tot);
tree[tot].x:=x;
tree[tot].count:=;
if x<tree[now].x then tree[now].son[]:=tot
else tree[now].son[]:=tot;
tree[tot].fa:=now;
splay(tot,,root);
if root=root1 then
begin
if tree[root].son[]<> then down(minsortgap,tree[root].x-tree[pre(root)].x);
if tree[root].son[]<> then down(minsortgap,tree[succ(root)].x-tree[root].x);
end
else down(mingap,x);
end; procedure init;
var
i:longint;
begin
read(n,m);
minsortgap:=maxlongint;
mingap:=maxlongint;
min:=maxlongint;
for i:= to n do
begin
read(a[i]);
b[i]:=a[i];
if flag=false then insert(a[i],root1);
if i> then insert(abs(a[i]-a[i-]),root2);
end;
readln;
end; procedure work;
var
i,x,y:longint;
c:char;
s:string;
begin
for i:= to m do
begin
read(c);
case c of
'I':begin
readln(c,c,c,c,c,x,y);
if x<n then
begin
if min>abs(b[x+]-y) then insert(abs(b[x+]-y),root2);
if min>abs(a[x]-b[x+]) then delete(abs(a[x]-b[x+]));
end;
down(min,abs(a[x]-y));
if flag=false then insert(y,root1);
a[x]:=y;
end;
'M':begin
readln(s);
if length(s)> then writeln(minsortgap)
else
begin
down(mingap,min);
writeln(mingap);
end;
end;
end;
end;
end; begin
init;
work;
end.
1058: [ZJOI2007]报表统计 - BZOJ的更多相关文章
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
- bzoj 1058: [ZJOI2007]报表统计 (Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...
- bzoj 1058: [ZJOI2007]报表统计
Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个 ...
- 【BZOJ】1058: [ZJOI2007]报表统计(splay+set)
http://www.lydsy.com/JudgeOnline/problem.php?id=1058 当复习一下splay.... 做法很简单..... 观察得知每一次插入一个点只需要维护前后的绝 ...
- [BZOJ 1058] [ZJOI2007] 报表统计 【平衡树】
题目链接:BZOJ - 1058 题目分析 这道题看似是需要在序列中插入一些数字,但其实询问的内容只与相邻的元素有关. 那么我们只要对每个位置维护两个数 Ai, Bi, Ai 就是初始序列中 i 这个 ...
- BZOJ 1058: [ZJOI2007]报表统计 multiset + 卡常
Code: #include<bits/stdc++.h> #define maxn 600000 #define inf 1000000000 using namespace std; ...
- bzoj 1058 [ZJOI2007]报表统计(set)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1058 [题意] 一个序列,提供插入,查询相邻最小差值,查询任意最小差值的操作. [思路 ...
- AC日记——[ZJOI2007]报表统计 bzoj 1058
1058 思路: 平衡树的题: 然而我的平衡树写一次炸一次QwQ: 而且各种tle: 所以stl水过: 代码: #include <set> #include <cstdio> ...
- bzoj 1058: [ZJOI2007]报表统计【set】
我想写FHQtreap的!是set自己跑进代码的!因为太好写了 是有点慢--洛谷上不吸氧会T一个点 就是,用一个set p维护所有点值,ans维护MIN_SORT_GAP的答案,每次insert一个点 ...
随机推荐
- saltstack实战3--配置管理之YAML语法
本文来自如下链接http://docs.saltstack.cn/topics/yaml/index.html 了解YAML 默认的SLS文件的renderer是YAML renderer.YAML是 ...
- Linux 命令 - less: LESS IS MORE
less 程序是为了替换早期 UNIX 中的 more 程序.less 这个名字是对短语 "less is more" 开了个玩笑,该短语是现代派建筑师和设计师们的座右铭. les ...
- AES加密和Base64混合加密
/// <summary> /// AES加密方法(AES加密和Base64混合加密) /// </summary> /// <param name="toEn ...
- php对UTF8字体串进行单字分割返回数组
在网上查了很多字符串分割方法,都无法正确对UTF8字符串进行正确分割返回单个字符的数组.经过对FTU8编码的分析写出了下面的方法对UTF8进行分割.本人测试可用.本方法只支持UTF8编码的,其它编码转 ...
- oracle instantclient basic +pl/sql 安装和配置
oracle instantclient basic +pl/sql 安装和配置 大家都知道,用PL/SQL连接Oracle,是需要安装Oracle客户端软件的,oracle客户端有点大,比较耗资源. ...
- RSS订阅推荐
科技新闻 虎嗅网 http://www.huxiu.com/ 科技博客的新生力量,文章以观点鲜明出名: 36氪 http://www.36kr.com/ 科技博客,关注创业,可以免费发表创业公司新闻 ...
- iOS UIView 快速修改 frame
我们修改frame中的某个值,需要进行繁琐的书写,例如: (1). 直接设置位置大小 view.frame = CGRectMake(0, 0, 320, 150); (2). 只修改某个值 view ...
- 用sublime编译C++的方法
sublime代码高亮这么好看,怎么能不用sublime敲代码呢: ) 本人用的版本是sublime Text3中文版 在网上查了查,自己的sublime现在也能编译C++了,设置步骤如下: 1.找到 ...
- Poj 2707 Copier Reduction
1.Link: http://poj.org/problem?id=2707 2.Content: Copier Reduction Time Limit: 1000MS Memory Limit ...
- CMake基础教程
如果需要配置和检查我们工程中的所有依赖,那么可以选用CMake工具:但是,这并不是必须的,因为我们可以使用其他的工具或者是IDE(比如Makefiles或者Visual Studio)来配置我们的工程 ...