在最開始的時候,有乙個長度為n
n的整數序列,並且有以下三種操作:
首先操作三是很簡單的,我們只要寫一棵平衡樹,維護每乙個數字的前驅後繼,每次插入乙個數就判斷它與它前驅後繼的差值是否小於min
nmin
n。如果小於就更新。
對於第二問,定義las
t[i]
last
[i]表示原序列第i
i個數字後面插入的最後乙個數字,如果我們在原序列第i
i個數字後面插入x
x,那麼會受影響的只有abs
(a[i
+1]−
last
[i])
abs(
a[i+
1]−l
ast[
i])。因為在las
t[i]
last
[i]和a
[i+1
]a[i
+1]中插入了乙個新的數字。
同時我們還加入了兩個新的數字abs
(x−l
ast[
i])a
bs(x
−las
t[i]
)和abs
(x−a
[i+1
])ab
s(x−
a[i+
1])。而我們要求這些數字的最小值,所以我們可以將所有這些數字插入乙個小跟堆中。每次去最小值。
那麼如果最小值本來應該刪除的話怎麼辦呢?我們可以再建乙個小根堆,把要刪除的數字插入小根堆中。如果此時的最小值和要刪除數字的最小值一樣,那麼這個最小值就是要刪除的,兩個堆都彈出即可。
時間複雜度o(m
log(n
+m))
o(mlog(n
+m))
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int n=
1000010
,inf=
1e9;
int n,m,root,minn,a[n]
,last[n]
;char ch[30]
;priority_queue<
int> q,p;
struct treenode
;struct treap
void
build()
void
zig(
int&x)
void
zag(
int&x)
void
insert
(int
&x,int val)
if(tree[x]
.val==val)
if(val.val)
else
}int
pre(
int x,
int val)
intnext
(int x,
int val)
intcnt
(int x,
int val)
}treap;
intmain()
}while
(m--)if
(treap.
cnt(root,y)
>
1) minn=0;
if(minn)
last[x]
=y;}
else
if(ch[5]
=='s'
)printf
("%d\n"
,minn)
;else
}return0;
}
洛谷 1110 報表統計 線段樹
題解 考慮離散化,利用兩顆線段樹來維護合適的資訊求解兩個詢問。min gap 求相鄰的差值絕對值最小。建立線段樹儲存差值的出現次數,詢問時求差值最小的那個即可。記位置i ii初始值為a i a i a i 新插入的值為b i b i b i 初始b i a i b i a i b i a i 當在位...
洛谷P3369 模板 普通平衡樹
本蒟蒻最近剛剛學會平衡樹,特來寫篇部落格以加深印象。我的意思是若寫的不好望各位奆佬多多包含!插入 x 數 刪除 x 數 若有多個相同的數,因只刪除乙個 查詢 x 數的排名 排名定義為比當前數小的數的個數 1 若有多個相同的數,因輸出最小的排名 查詢排名為 x 的數 求 x 的前驅 前驅定義為小於 x...
洛谷 P3391 模板 文藝平衡樹
真正的模板題,先用splay把這個題打熟了再來做這個題qwq splay的基本操作我就不講了,直接說一說這個題的做法 首先我們把序列放到一棵樹上,使得這棵樹的中序遍歷為原序列,這個建樹操作和線段樹類似,遞迴建立左右兒子,然後進行兩個操作 f in dfind find 獲取序列第x xx位置上的值 ...