小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寫了乙個程式,使
得程式可以自動完成這些操作,但是他發現對於一些大的報表他的程式執行得很慢,你能幫助他改進程式麼?
正解:堆+平衡樹
又墮落了qwq,說好的平衡樹呢?
對於第乙個操作,我們鍊錶維護一下即可
對於第二個詢問,我們維護乙個堆,我們每加入乙個元素就把與前後差值加入堆中,堆中記錄後繼,便於刪除.
對於第三個詢問,答案單調不公升,直接平衡樹維護全域性變數,插入時取min即可
#include #include #include #include #include #include #include #include #define rg register
#define il inline
#define iter iterator
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int n=1000005,inf=2e9;
int n,m,nxt[n],cnt=0,pre[n],val[n],last[n],b[n];
char s[41];
struct node
};priority_queueq;
multisetg;
multiset::iter it;
void work()
); g.insert(val[i]);
} sort(b+1,b+n+1);
for(int i=2;i<=n;i++)ans=min(ans,b[i]-b[i-1]);
g.insert(-inf);g.insert(inf);
while(m--));
if(xit=g.lower_bound(z);
if(*it!=-inf)
it=g.upper_bound(z);
if(*it!=inf)ans=min(ans,abs(*it-z));
g.insert(z);
} else if(s[4]=='g')
}} else printf("%d\n",ans); }}
int main()
bzoj1058 ZJOI2007 報表統計
小q的媽媽是乙個出納,經常需要做一些統計報表的工作。今天是媽媽的生日,小q希望可以幫媽媽分擔一些工作,作為她的生日禮物之一。經過仔細觀察,小q發現統計一張報表實際上是維護乙個可能為負數的整數數列,並且進行一些查詢操作。在最開始的時候,有乙個長度為n的整數序列,並且有以下三種操作 insert i k...
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...