給出n(n<=250000)輛賽車,i賽車初始在xi,速度為vi,賽車在比賽時會發生超車(不會相撞)。求超車次數%1000000,並輸出前10000次(不足10000次有幾次輸出幾次)超車,格式為x y,表示x超過y,時間靠前的先輸出,時間相同位置靠前的先輸出,保證沒有時間相同位置也相同的超車。
第一問顯然就是逆序對,用二路歸併求解即可。關鍵就是這個第二問難,好像除了o(n^2)的掃瞄沒有辦法。
如果總體來看,非常難處理,我們要把總體的問題盡量縮小,才能方便的處理:對於超車,肯定是相鄰兩個先超車(超車完之後相鄰位置就改了)。有了這個思路,我們可以剛開始相鄰算出超車時間,然後從中挑出乙個小的,這就是第一次超車,超車完畢之後,因為相鄰位置交換,所以要重新對左右兩個車進行計算(利用鍊錶就可以快速找到相鄰位置),算出新的超車時間,然後又挑出乙個小的,重新計算……
每次挑出小的,讓我們想到了堆,至此,這道題就解完了。下面給出示意圖:
}; //賽車的結構體
struct heap
int readi(int &x) //讀入優化
while ('0'
<=ch&&ch<='9') tot=tot*10+ch-48,ch=getchar();
x=tot*f;
return eoln(ch);
}void msort(int l,int r) //二路歸併
void put_s(int x,int y,double ti,double dis) //放入堆中
;son=len_s;
while (son!=1&&heap_s[son]>1])
}void del_s() //刪除堆頂
}double getti(int i,int j) //得到i和j相遇的時間
double getdis(int i,int j) //得到i和j相遇的位置
int main()
//x和y交換過後,x和r[y]產生新狀況
if (lx) //x和y交換後,y和l[x]產生新狀況
l[x]=y;r[y]=x;r[x]=ry;l[y]=lx; //修正鍊錶
}return
0;}
堆 鍊錶 POJ2274 The Race
題面在這裡 這道題想法很簡單,但是實現比較複雜 參考隔壁神犇zzk的題解。昨天寫好 後,一wa到底,查了近乙個小時 各位同學寫的時候小心。第一問很簡單,典型的逆序數 由於v很小,可以用陣列代替樹狀陣列 至於第二問,要求按順序輸出前10000個 超越事件 自然就想到用堆來儲存 超越事件 這裡使用了二叉...
堆 鍊錶實現
小頂堆大頂堆的概念大家應該都很熟悉了,如果不了解,可以搜尋一下,網上很多介紹,而且很多原始碼實現,都很簡單。不過從網上看了一些堆的實現,都是用陣列的。但是陣列有乙個缺陷,需要擴充套件時,就要複製原來的記憶體,申請新的空間。所以我在想能不能用鍊錶,發現還真可以,就湊湊寫了個 最後 是寫完了,發現其實鍊...
BZOJ 1150 (堆 鍊錶)
你在一家 it 公司為大型寫字樓或辦公樓 offices 的計算機資料做備份。然而資料備份的工作是枯燥乏味 的,因此你想設計乙個系統讓不同的辦公樓彼此之間互相備份,而你則坐在家中盡享計算機遊戲的樂趣。已知辦公 樓都位於同一條街上。你決定給這些辦公樓配對 兩個一組 每一對辦公樓可以通過在這兩個建築物之...