小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寫了乙個程式,使得程式可以自動完成這些操作,但是他發現對於一些大的報表他的程式執行得很慢,你能幫助他改進程式麼?
第一行包含兩個整數n,m,分別表示原數列的長度以及操作的次數。第二行為n個整數,為初始序列。接下來的m行每行乙個操作,即「insert i k」,「min_gap」,「min_sort_gap」中的一種(無多餘空格或者空行)。
對於每乙個「min_gap」和「min_sort_gap」命令,輸出一行答案即可。
3 55 3 1
insert 2 9
min_sort_gap
insert 2 6
min_gap
min_sort_gap22
1n , m ≤500000 對於所有的資料,序列內的整數不超過5*10^8。 [
submit][
status][
discuss]
分析:
這題有兩種詢問:
1.詢問相鄰兩個數的差值的最小值
2.詢問排序後相鄰兩個數的差值的最小值
這道題比較簡單的一點就是,我們的詢問都是整個佇列的資訊,所以我們就可以整個佇列一起考慮
這道題涉及到了兩種資料結構:
splay和樹狀陣列
我們先看插入操作:
void insert(int x,int z)
詢問一:
這個詢問我們用splay維護:
精髓就在於update
void update(int bh)
else lval[bh]=key[bh];
if (ch[bh][1]&&ch[bh][1]!=1&&ch[bh][1]!=2)
else rval[bh]=key[bh];
}
lval:維護該結點前驅的最大值
rval:維護該結點後繼的最小值
minv:整個序列的相鄰元素最小差值
詢問二:
我們用set維護整個序列排序後的最小差值
void push(int z)
s.insert(z);
}
練碼力
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int n=1000010;
const
int inf=1e9;
int n,m,min_sort_gap;
int rval[n],lval[n],tree[n]; //tree是樹狀陣列
int minv[n],sz[n],pre[n],ch[n][2],cnt[n],a[n],root,key[n];
int top;
struct node;
node t[n<<2];
set s;
int get(int bh)
int getsum(int x) //字首和
void add(int x,int val)
void update(int bh)
else lval[bh]=key[bh];
if (ch[bh][1]&&ch[bh][1]!=1&&ch[bh][1]!=2)
else rval[bh]=key[bh];
}void push(int z)
s.insert(z);
}void rotate(int bh)
void splay(int bh,int mb)
int get_kth(int k) //排名
}}void insert(int x,int z)
int main()
char s[20];
for (int i=1;i<=m;i++)
else
if (s[4]=='s')
printf("%d\n",min_sort_gap);
else
printf("%d\n",minv[root]);
}return
0;}
bzoj1058 ZJOI2007 報表統計
傳送門 題解 這個insert操作好py啊是不是用set就能搞搞啊。什麼?你跟我講t了?讀入優化?還是t?卡了卡常,發現乙個東西用priority queue就夠了。然後12s過了。include include include include include include include usi...
bzoj1058 ZJOI2007 報表統計
題目大意 給定乙個序列,有多次詢問和修改,將新元素插在原數列位置的後面,詢問相鄰元素差值最小,和數列中兩元素最小的差。stl解法 用乙個set去維護相鄰兩個數差的最小值,用乙個堆去維護所有序列中最小的差 includeusing namespace std define inf 1000000000...
BZOJ1058 ZJOI2007 報表統計
bzoj1058 zjoi2007 報表統計 小q的媽媽是乙個出納,經常需要做一些統計報表的工作。今天是媽媽的生日,小q希望可以幫媽媽分擔一些工作,作為她的生日禮物之一。經過仔細觀察,小q發現統計一張報表實際上是維護乙個可能為負數的整數數列,並且進行一些查詢操作。在最開始的時候,有乙個長度為n的整數...