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 ...
随机推荐
- 【OSG】运行OSG示例出现的奶牛不完整问题
发现一个很奇怪的问题:我用笔记本运行OSG里面的示例,出现的图案总是不完整显示的,以经典的奶牛图案为例,如图. 图一是我电脑上的情况,正常情况应该是图二.不知道这是什么原因,难道是我电脑显卡的原因吗? ...
- 多个表单数据提交下的serialize()应用
在实际开发场景中,难免遇到需要多个表单的数据传递问题. 之所以要进行多表单的数据传递是因为可以进行数据分组,便于数据的维护. 这个时候,出于不依赖jquery的考虑,有一个原生js函数来解决这个问题无 ...
- 【log4net】- 非常完善的Log4net详细说明
1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual S ...
- CheckStateChanged(复选框选中状态更改事件)和 CheckedChanged(单选按钮选中状态更改事件)二者区别?
CheckStateChanged(复选框选中状态更改事件)和 CheckedChanged(单选按钮选中状态更改事件)二者区别: 复选框控件(CheckBox)提供了CheckedChanged控件 ...
- sql sever误删数据库
在sql sever 2008 r2中,我想把一个数据库添加到DATA中,结果发现被占用,我就打算解除占用后再进行复制,本来应该先是让数据库脱离,再复制,结果,我自作聪明地右键数据库,选择了删除,结果 ...
- Python re(正则表达式)模块
python正则表达式 正则表达式是一个特殊的字符序列,它能帮助我们方便的检查一个字符串是否与某种模式匹配.Python自1.5版本起增加了re模块,它提供Perl风格的正则表达式模式.re模块使Py ...
- Django 2.0 学习(08):Django 自动化测试
编写我们的第一个测试 确定bug 幸运的是,在polls应用中存在一个小小的bug急需修复:无论Question的发布日期是最近(最后)的日期,还是将来很多天的日期,Question.was_publ ...
- hdu 1115 Lifting the Stone (数学几何)
Lifting the Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 【刷题】BZOJ 4827 [Hnoi2017]礼物
Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在 ...
- [洛谷P1341]无序字母对
题目大意:给一张无向图,找一条字典序最小的欧拉路径 题解:若图不连通或有两个以上的奇数点,则没有欧拉路径,可以$dfs$,在回溯时把这个节点加入答案 卡点:没有在回溯时加入答案,导致出现了欧拉路径没走 ...