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 ...
随机推荐
- 【Docker 命令】- kill命令
docker kill :杀掉一个运行中的容器. 语法 docker kill [OPTIONS] CONTAINER [CONTAINER...] OPTIONS说明: -s :向容器发送一个信号 ...
- Winform 数据绑定
1.DataGridView数据绑定 namespace WindowsFormsApplication1 { public partial class Form1 : Form { private ...
- DELPHI Showmodal 模式窗体
Showmodal 是个函数, Show 是个过程 1. Showmodal: 概念 : 当你调用一个窗口用 SHOWMODAL 时 , 当这个窗口显示出来后 , 程序不会继续自己执行 , 而 ...
- C#下载网页
System.Net.WebClient wc = new System.Net.WebClient(); Byte[] pageData = wc.DownloadData("网页地址&q ...
- 【Windows】Windows服务管家婆之Service Control Manager
Service Control Manager,服务控制管理器,人称SCM就是它!在Windows内核中,都可以看到她忙碌的身影,可以说是系统服务和驱动的管家婆了! SCM管家婆起早贪黑,每次 ...
- Lucene笔记一
Lucene就是一个全文检索的工具,建立索引用的,类似于新华字典的目录 这里使用的是lucene-4.4.0版本,入门代码所需jar包如下图所示(解压lucene-4.4.0后的目录): 入门代码: ...
- (转)如何用U盘创建Linux系统盘
(转)http://teliute.org/linux/TeUbt/lesson60/lesson60.html 创建一个U盘linux安装盘,用以启动系统并安装: 1.启动盘创建器 1)点击主按钮, ...
- MySQL - General error: 1390 Prepared statement contains too many placeholders
报错原因:预处理 SQL语句时使用的占位符数量超过了最大限制(默认65535). 解决方案:拆分查询语句,每次使用的占位符低于限制即可.
- 项目管理---git----快速使用git笔记(四)------远程项目代码的首次获取
使用git最常见的场景是 你需要参与到一个项目中,而这个项目的代码,同事已经上传到github或者https://coding.net了. 这时候他会给你一个项目代码的远程仓库链接. 例如: http ...
- ucenter通信实现同步登录、同步退出(详细)
首先,需要去官网下载一个ucenter的包.然后解压下来. 先把ucenter/ucenter这个文件夹复制到你的项目根目录下改名为uc_server;(这里只是我建议修改,以便于我下面写的配置); ...