bzoj 1058 bst
因为是数列的维护,所以我们可以考虑用splay来维护,每次在x插入的时候就在x+1前面插入就行了,然后用bst来维护两问的答案,但是应该会tle。我们来考虑这个问题的性质,首先因为这个数列没有删除操作,所以每个数插入进去之后就不会出来了,换句话说,就是假设insert(x,y)那么y这个值和前面的那个数可以更新相邻差值的答案,且这个不会因为其他的插入操作而使得这个差值消失(消失值类似(x,y)插入,那么之前在x处插入的点与x+1的差值会消失),所以我们只需要存储每个位置最后插入的数,那么对于一个插入(x,y)我们只需要判断x位置是否插入过值然后讨论就行了。那么对于另一个全局差值的更新我们只需要用bst维护所有插入的数,每插入一个数就找前驱后继来更新答案就行了。因为这个答案是递减的,所以当答案为0的时候不用更新就行了,这样大概可以快3-4s。
反思:很早的时候用pascal写了splay的,满满的tle,然后转了C++之后用的set和map,快了好多,也好写了好多= =
/**************************************************************
Problem: 1058
User: BLADEVIL
Language: C++
Result: Accepted
Time:9924 ms
Memory:40700 kb
****************************************************************/
//By BLADEVIL
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#define maxn 1000010
#define inf (~0U>>1)
using namespace std;
int n,m,ans;
int a[maxn],b[maxn];
char c[];
map<int,int>ms;
set<int>bt;
void update(int x){
if (bt.count(x)) {
ans=; return;
}
set<int>::iterator p=bt.upper_bound(x);
if (p!=bt.end()) ans=min(ans,abs(*p-x));//,printf("%d->%d ",x,*p);
--p;
if (*p!=-inf) ans=min(ans,abs(*p-x));//,printf("%d<-%d",x,*p); printf("\n");
bt.insert(x);
}
void insert(int x){
map<int,int>::iterator p=ms.find(x);
if (p!=ms.end()) p->second++; else ms.insert(pair<int,int>(x,));
}
void erase(int x){
map<int,int>::iterator p=ms.find(x);
if (p->second==) ms.erase(p); else p->second--;
}
void printbt(){
for (set<int>::iterator p=bt.begin();p!=bt.end();p++) printf("%d ",*p); printf("\n");
}
void printms(){
for (map<int,int>::iterator p=ms.begin();p!=ms.end();p++) printf("|%d %d\n",p->first,p->second);
}
int main(){
ans=inf; bt.insert(-inf);
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<n;i++) insert(abs(a[i]-a[i+]));
for (int i=;i<=n;i++) {
if (bt.count(a[i])) {
ans=; break;
}
update(a[i]);
}
//printms(); printbt();
while (m--){
scanf("%s",&c);
if (c[]=='I'){
int x,y;
scanf("%d%d",&x,&y);
if (x==n){
if (b[x]) insert(abs(b[x]-y)); else insert(abs(a[x]-y));
} else {
if (b[x]){
erase(abs(b[x]-a[x+]));
insert(abs(b[x]-y)); insert(abs(a[x+]-y));
} else {
erase(abs(a[x]-a[x+]));
insert(abs(a[x]-y)); insert(abs(a[x+]-y));
}
}
b[x]=y;
if (ans) update(y);
} else
if (c[]=='G') {
printf("%d\n",ms.begin()->first);
} else printf("%d\n",ans);
}
return ;
}
/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Time_Limit_Exceed
****************************************************************/
//By BLADEVIL
var
n, m :longint;
root, sroot :longint;
father, size :array[-..] of longint;
tree, a :array[-..] of int64;
son :array[-..,..] of longint;
numt, t, st :longint;
tot :longint;
left, right, b_size :array[..] of longint;
key :array[..] of int64;
print :int64;
function abs(x:int64):int64;
begin
if x< then exit(-x) else exit(x);
end;
function min(a,b:int64):int64;
begin
if a>b then min:=b else min:=a;
end;
procedure update(x:longint);
begin
size[x]:=size[son[x][]]+size[son[x][]]+;
end;
function build(l,r:longint):longint;
var
mid :longint;
begin
mid:=(l+r)>>;
build:=mid;
tree[mid]:=a[mid];
if mid->=l then
begin
son[mid][]:=build(l,mid-);
father[son[mid][]]:=mid;
end;
if mid+<=r then
begin
son[mid][]:=build(mid+,r);
father[son[mid][]]:=mid;
end;
update(mid);
end;
procedure rotate(x,y:longint);
var
f :longint;
begin
f:=father[x];
son[f][y]:=son[x][y xor ];
father[son[x][y xor ]]:=f;
if f=root then root:=x else
if f=son[father[f]][] then
son[father[f]][]:=x else
if f=son[father[f]][] then
son[father[f]][]:=x;
son[x][y xor ]:=f;
father[x]:=father[f];
father[f]:=x;
update(f);
update(x);
end;
procedure splay(x,y:longint);
var
u, v :longint;
begin
while father[x]<>y do
if father[father[x]]=y then
rotate(x,ord(x=son[father[x]][])) else
begin
if x=son[father[x]][] then u:= else u:=-;
if father[x]=son[father[father[x]]][] then v:= else v:=-;
if u*v= then
begin
rotate(father[x],ord(x=son[father[x]][]));
rotate(x,ord(x=son[father[x]][]));
end else
begin
rotate(x,ord(x=son[father[x]][]));
rotate(x,ord(x=son[father[x]][]));
end;
end;
update(x);
end;
function find(x:int64):int64;
var
t :longint;
begin
t:=root;
while true do
begin
if size[son[t][]]+=x then exit(t) else
if size[son[t][]]+>x then t:=son[t][] else
begin
x:=x-(size[son[t][]]+);
t:=son[t][];
end;
end;
end;
procedure left_rotate(var t:longint);
var
k :longint;
begin
k:=right[t];
right[t]:=left[k];
left[k]:=t;
b_size[k]:=b_size[t];
b_size[t]:=b_size[left[t]]+b_size[right[t]]+;
t:=k;
end;
procedure right_rotate(var t:longint);
var
k :longint;
begin
k:=left[t];
left[t]:=right[k];
right[k]:=t;
b_size[k]:=b_size[t];
b_size[t]:=b_size[left[t]]+b_size[right[t]]+;
t:=k;
end;
procedure maintain(var t:longint;flag:boolean);
begin
if not flag then
begin
if b_size[left[left[t]]]>b_size[right[t]] then
right_rotate(t) else
if b_size[right[left[t]]]>b_size[right[t]] then
begin
left_rotate(left[t]);
right_rotate(t);
end else exit;
end else
begin
if b_size[right[right[t]]]>b_size[left[t]] then
left_rotate(t) else
if b_size[left[right[t]]]>b_size[left[t]] then
begin
right_rotate(right[t]);
left_rotate(t);
end else exit;
end;
maintain(left[t],false);
maintain(right[t],true);
maintain(t,true);
maintain(t,false);
end;
procedure insert(var t:longint;v:int64);
begin
if t= then
begin
inc(tot);
t:=tot;
key[t]:=v;
b_size[t]:=;
left[t]:=;
right[t]:=;
end else
begin
b_size[t]:=b_size[t]+;
if v<key[t] then insert(left[t],v) else insert(right[t],v);
maintain(t,v>=key[t]);
end;
end;
function pred(var t:longint;v:int64):int64;
begin
if t= then exit(maxlongint>>);
if key[t]>v then pred:=pred(left[t],v) else
begin
pred:=pred(right[t],v);
if pred=maxlongint>> then exit(key[t]);
end;
end;
function succ(var t:longint;v:int64):int64;
begin
if t= then exit(maxlongint>>);
if key[t]<v then succ:=succ(right[t],v) else
begin
succ:=succ(left[t],v);
if succ=maxlongint>> then exit(key[t]);
end;
end;
function delete(var t:longint;v:int64):int64;
begin
b_size[t]:=b_size[t]-;
if (key[t]=v) or (v>key[t]) and (right[t]=) or (v<key[t]) and (left[t]=) then
begin
delete:=key[t];
if (left[t]=) or (right[t]=) then
t:=left[t]+right[t] else
key[t]:=delete(left[t],v+);
end else
if v>=key[t] then delete:=delete(right[t],v) else delete:=delete(left[t],v);
end;
procedure change(x:longint;y:int64);
var
q, p :int64;
begin
splay(x,sroot);
p:=size[son[root][]];
p:=find(p);
splay(p,root);
delete(t,abs(tree[p]-tree[root]));
insert(t,abs(y-tree[p]));
insert(t,abs(y-tree[root]));
inc(n);
a[n]:=y;
tree[n]:=y;
son[son[root][]][]:=n;
father[n]:=son[root][];
size[n]:=;
update(son[root][]);
update(root);
p:=pred(numt,y);
q:=succ(numt,y);
if p=maxlongint>> then insert(st,abs(q-y)) else
if q=maxlongint>> then insert(st,abs(p-y)) else
insert(st,min(abs(p-y),abs(q-y)));
insert(numt,y);
end;
function mini(var t:longint):int64;
begin
if left[t]= then exit(key[t]) else exit(mini(left[t]));
end;
procedure init;
var
i :longint;
x, y :int64;
begin
readln(n,m);
for i:= to n do read(a[i]);
readln;
numt:=;
st:=;
for i:= to n do
begin
x:=succ(numt,a[i]);
y:=pred(numt,a[i]);
insert(numt,a[i]);
if x=maxlongint>> then insert(st,abs(y-a[i])) else
if y=maxlongint>> then insert(st,abs(x-a[i])) else
insert(st,min(abs(x-a[i]),abs(y-a[i])));
end;
t:=;
for i:= to n- do
insert(t,abs(a[i+]-a[i]));
fillchar(son,sizeof(son),);
sroot:=-;
inc(n);
root:=build(,n);
father[root]:=sroot;
end;
procedure main;
var
i :longint;
s :ansistring;
ch :char;
x :longint;
y :int64;
begin
print:=maxlongint>>;
for i:= to m do
begin
read(ch);
if ch='I' then
begin
s:='';
while ch<>' ' do
begin
s:=s+ch;
read(ch);
end;
readln(x,y);
change(x+,y);
end else
begin
readln(s);
if s[]='S' then
begin
if print= then
begin
writeln();
end else
begin
if mini(st)<print then print:=mini(st);
writeln(print);
end;
end else
writeln(mini(t));
end;
end;
end;
begin
init;
main;
end.
bzoj 1058 bst的更多相关文章
- [BZOJ 1058] [ZJOI2007] 报表统计 【平衡树】
题目链接:BZOJ - 1058 题目分析 这道题看似是需要在序列中插入一些数字,但其实询问的内容只与相邻的元素有关. 那么我们只要对每个位置维护两个数 Ai, Bi, Ai 就是初始序列中 i 这个 ...
- [BZOJ 1058] 报表统计
Link: BZOJ 1058 传送门 Solution: 为了这道题今天下午一直都在和常数大战…… 1.对于询问1,我们记录每个数末位置的数$T[i]$和初始位置$S[i]$ 用平衡树维护所有差值, ...
- bzoj 1058 [ZJOI2007]报表统计(set)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1058 [题意] 一个序列,提供插入,查询相邻最小差值,查询任意最小差值的操作. [思路 ...
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
- bzoj 1058: [ZJOI2007]报表统计
Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个 ...
- bzoj 1058: [ZJOI2007]报表统计 (Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...
- AC日记——[ZJOI2007]报表统计 bzoj 1058
1058 思路: 平衡树的题: 然而我的平衡树写一次炸一次QwQ: 而且各种tle: 所以stl水过: 代码: #include <set> #include <cstdio> ...
- BZOJ 1058
服气!我果然就是个傻逼. 傻兮兮地感觉两个数之间的差距无需删除一些答案,妈个鸡就只加入了一些新的答案忘记了去掉无效的答案.我果然是傻逼,经验不足脑子笨... 这么水的题...不说了,说多了都是泪. 自 ...
- BZOJ 1058 报表统计 (STL)
题解:数据结构的基本操作,用STL可以完美实现,就是比较慢…… #include <cstdio> #include <map> #include <set> #i ...
随机推荐
- JavaScript数组自定义属性
我们可以以json键值对的形式自定义属性. 首先定义一个JS数组JSarray. 然后按json键值对的形式进行赋值. 最后在控制台显示结果. 代码如下: var JSarray = new Arra ...
- 从1到n的阶乘的和(python)
今天在百度上逛一些ctf的平台,偶然发现一道编程题,于是乎,便用我刚刚学的python知识解了这道题 题目的描述是这样的: 计算1!+2!+3!+...+6666!后五位. 这个计算量很大啊,我还是用 ...
- CDN概念基本介绍
CDN概念基本介绍 一 . CDN简介 什么是CDN? CDN的全称是Content Delivery Network,即内容分发网络. 其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的 ...
- IO Model- 同步,异步,阻塞,非阻塞
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- CSS定义input disabled样式
disabled 属性规定应该禁用 input 元素.被禁用的 input 元素既不可用,也不可点击.可以设置 disabled 属性,直到满足某些其他的条件为止(比如选择了一个复选框等等).然后,就 ...
- [CF1037H] Security
题目链接 codeforces. 洛谷. Solution 按照套路,可以\(SAM\)上线段树合并求出\(endpos\)集合,然后随便贪心一下就好了. #include<bits/stdc+ ...
- POJ2104:K-th Number——题解
http://poj.org/problem?id=2104 题目大意:求区间第k小. —————————————————————————— 主席树板子题. ……我看了半天现在还是一知半解的状态所以应 ...
- BZOJ1013:[JSOI2008]球形空间产生器——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1013 Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在 ...
- 洛谷 P3332 [ZJOI2013]K大数查询 解题报告
P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...
- Spring中事务传播行为类型
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 说明 PROPAGATION ...