bzoj1058: [zjoi2007]報表統計
小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。
噁心到極致的卡常題。。。
維護兩個$treap$即可。
為什麼不用$splay$?
因為這個題目$bzoj$用事實告訴我們:$splay$的常數是$treap$的許多倍。。。
第一顆$treap$:維護每個點,每次新加入乙個點時,找到前驅後繼,維護第$3$個操作的答案。
第二顆$treap$:每次加入點時,維護相鄰兩個點之差的絕對值。
然後就沒了。
但是這題瘋狂卡常。。。
對於第$2$個操作,我們注意到,加入乙個點位置是$pos$時,$pos$與$pos-1$的差值不會消失,所以可以用乙個$ans$來維護$pos$與前驅的之間的值。
而$pos$與$pos+1$之間可能加入數字,所以用$treap$維護。不過,若差值小於$ans$,就不用再加入$treap$中了。
還有,對於第$3$個操作,在統計是只要發現有兩個數字相同,就做個標記,到後面詢問時直接輸出$0$即可。
以上所說的差值都要加絕對值。
然後就可以跑了。。。
附**:
#include#include#include#define maxn 500010#define max 999999999
using namespace std;
int n,m,minn=max;
int head[maxn],last[maxn];
bool flag;
struct node
};node* one;node* two;
inline int read()
while(c>='0'&&c<='9')
return date*w;
}inline void write(int x)
if(x>9)write(x/10);
putchar(x%10+'0');
}inline long long abs(const long long x)
inline long long min(const long long x,const long long y)
void turn(node* &u,int f)
void insert(node* &u,int x)
else if(u->v==x)
int y=u->vson[y],x);
if(u->son[y]->w>u->w)turn(u,y^1);
else maintain(u);
}void remove(node* &u,int x)
else
}else
} if(u!=null)maintain(u);
} else
}int kth(node* u,int k)
void front(node* u,int k,int &ans)
else if(u->v>=k)
if(u->son[0]!=null)front(u->son[0],k,ans);
}void next(node* u,int k,int &ans)
else if(u->v<=k)
if(u->son[1]!=null)next(u->son[1],k,ans);
}void update(int v)
void work()
last[x]=y;
} else if(ch[4]=='g')
else }}
void init()
flag=false;
for(int i=1;i}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...