如果算上調stl的話這題似乎有很多種做法。。。調set、map,敲線段樹、spaly。。blabla
完美地避開了正解tat
題目要求維護一坨數,能夠隨時插入,查詢相鄰的數的最小差值,查詢任意兩數間的最小差值。
第二問比較好寫,然而人太弱不會調set。。於是寫了個treap。。每次插入後查詢一下前驅和後繼更新一下答案。然後這個答案顯然是遞減的,所以數列中有相同的數之後就不用理了(大概就是市面上各種spaly能夠卡時16s+過的原因。。。。)。
然而第一問就沒法用treap做了。。把原數列存在map裡面。
假設是在原數列第pos個元素後插入乙個數x,那麼x的右邊的那個數就是map[pos+1](如果posx左邊的那個數其實就是本來第pos個元素後面插了一坨數的最後乙個,用last[i]表示當前(插入x之前)第i個元素後面插進去的一坨數的最後乙個數的大小。
所以把x插進去後,原先的差值abs(last[pos]-map[pos+1])不存在了,新增了兩個差值為abs(last[pos]-x)和abs(x-map[pos+1])
用優先佇列(堆)維護下差值就好了。。。。。
具體姿勢:
對於新增的差值abs(last[pos]-x),它是不會被新增的數影響的。。然而abs(x-map[pos+1])可能因為之後在x後面插進去新的數而不存在。。。
判斷這個差值存不存在就看x是不是所在元素的最後一次插入的數。每次查詢的時候先把隊頭(小根堆頂)那些不存在的差值彈掉就行了。
事實證明這樣寫主要時間複雜度是在treap上= =。。。優先佇列的速度比treap高明到不知道**去了。。treap的速度又比spaly高明到不知道**去了。。。
跑了7s+。。。。並不算快tat
發現大部分的時間都是在treap建樹的時候。。。所以直接把數列排序後遞迴建樹(參見spaly建樹姿勢)就2028ms過了。。。速度#5。。
感覺第一問調set才是拯救常數的正確姿勢= =
改了點細節然後1980ms#3。。。。。#1喪心病狂甩別人若干條街
1 #include2 #include3 #include4 #include5 #include6 #include7view codeusing
namespace
std;
8const
int maxn=1000003;9
const
int inf=1002333333;10
struct
zs;13
int num[maxn],rnd[maxn],l[maxn],r[maxn],last[maxn>>1],map[maxn>>1],len[maxn>>1
];14
inti,j,n,m,minsg,ming,tot,rt,x,a,b,aft,pre;
15 priority_queueq;
16bool
operator
17int ra,fh;char
rx;18 inline int
read()
24char s[11
];25 inline void outx(int
x)29 inline void lturn(int &x,int r)
30 inline void rturn(int &x,int l)
31void ins(int &x,int
val)
33if(val
if(val>num[x])else minsg=0;40
}41void getpre(int now,int
val)
46void getaft(int now,int
val)
51 inline void insert(int p,int
x));57}
58void build(int l,int r,int &now,int
farnd)
64int
main());
71 memcpy(map,last,(n+1)<<2
);72
char
ch1;
73while(m--)
84while(ch1!='
p')ch1=getchar();85}
86}87return0;
88 }
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...