\(orz\)據說這個題有四種寫法…我孔乙己表示只會一種。(暫時的)
pp大廈有一間空的禮堂,可以為企業或者單位提供會議場地。這些會議中的大多數都需要連續幾天的時間(個別的可能只需要一天),不過場地只有乙個,所以不同的會議的時間申請不能夠衝突。也就是說,前乙個會議的結束日期必須在後乙個會議的開始日期之前。所以,如果要接受乙個新的場地預約申請,就必須拒絕掉與這個申請相衝突的預約。 一般來說,如果pp大廈方面事先已經接受了乙個會場預約,例如從10日到15日,就不會在接受與之相衝突的預約,例如從12日到17日。不過,有時出於經濟利益,pp大廈方面有時會為了接受乙個新的會場預約,而拒絕掉乙個甚至幾個之前預訂的預約。 於是,禮堂管理員qq的筆記本上筆記本上經常記錄著這樣的資訊: 本題中為方便起見,所有的日期都用乙個整數表示。例如,如果乙個為期10天的會議從「90日」開始到「99日」,那麼下乙個會議最早只能在「100日」開始。 最近,這個業務的工作量與日俱增,禮堂的管理員qq希望參加shtsc的你替他設計一套計算機系統,方便他的工作。這個系統應當能執行下面兩個操作: a操作:有乙個新的預約是從「start日」到「end日」,並且拒絕掉所有與它相衝突的預約。執行這個操作的時候,你的系統應當返回為了這個新預約而拒絕掉的預約個數,以方便qq與自己的記錄相校對。 b操作:請你的系統返回當前的仍然有效的預約的總數。
我們考慮建一棵平衡樹,那麼上邊的每個點代表的是乙個預約類,類裡面是兩個\(public\),\(l\)和\(r\)。
那麼事實上,我們可以每一次插入時\(logn\)二分查詢一下所在位置,然後向前向後不斷刪除有交集的\(nodes\)。
在這個地方記錄乙個巧妙的方法:\(set\)的二分刪除
就是這段**:
while(1)
it=qwq.lower_bound(temp);
if(it!=qwq.begin())
}break;
}
第乙個\(if\)向後刪除,第二個\(if\)向前刪除。
而這一段**的執行順序很顯然:
刪完二分所得位置之後的,刪不完就continue繼續刪,刪完二分所得位置之前的,刪不完就continue繼續刪,最後break。
反正我是被這個操作秀了一臉\(otz\).
嗯,這個操作就叫做二分刪除啦!!(霧
#include#include#include#includeusing namespace std;
struct hotel
hotel (int l,int r)
bool operator < (const hotel &cmp)const
it=qwq.lower_bound(temp);
if(it!=qwq.begin())
}break;
}qwq.insert(temp);
cout<\(ps:\) 用\(cin\)比\(scanf+register\)慢了1400ms……闊怕
用線段樹做……暫時還不會\(qaq\)。
又留了乙個坑\(orz\)
SHOI2009 會場預約
首先我們要知道,滿足什麼性質的線段,才與當前這個插入的線段有交集呢?那就是 線段的左端點在 1,r 但是線段的右端點大於l,所以,我們直接把線段的左端點當成下標,值當成r,插入到線段樹當中即可。然後刪除操作 只要在區間 1,r 並且區間max大於等於當前插入的線段的左端點,那麼就去刪除即可。同時線段...
SHOI2009 會場預約
題意 支援操作 按順序在數軸上插入一條線段,刪除並詢問所有與這條線段有交的線段個數。詢問當前數軸上一共有多少條線段。想做了很久的題 觀察到和線段 l i,r i 有交的線段,實際上就是右端點 ge l i 並且左端點 le r i 的一些線段。我們可以把所有線段按照右端點第一關鍵字,左端點第二關鍵字...
SHOI2009 會場預約 線段樹
pp大廈有一間空的禮堂,可以為企業或者單位提供會議場地。這些會議中的大多數都需要連續幾天的時間 個別的可能只需要一天 不過場地只有乙個,所以不同的會議的時間申請不能夠衝突。也就是說,前乙個會議的結束日期必須在後乙個會議的開始日期之前。所以,如果要接受乙個新的場地預約申請,就必須拒絕掉與這個申請相衝突...