NOIP2012提高組 開車旅行 題解

2021-07-26 17:39:44 字數 1904 閱讀 6264

題目連線:

題目描述:

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為hi,城市 i 和城市 j 之間的距離 d[i,j]恰好是這兩個城市海拔高度之差的絕對值,即d[i,j] = |hi− hj|。

旅行過程中,小 a 和小 b 輪流開車,第一天小 a 開車,之後每天輪換一次。他們計畫選擇乙個城市 s 作為起點,一直向東行駛,並且最多行駛 x 公里就結束旅行。

小 a 和小 b的駕駛風格不同,小 b 總是沿著前進方向選擇乙個最近的城市作為目的地,而小 a 總是沿著前進方向選擇第二近的城市作為目的地(注意:本題中如果當前城市到兩個城市的距離相同,則認為離海拔低的那個城市更近)。

如果其中任何一人無法按照自己的原則選擇目的城市,或者到達目的地會使行駛的總距離超出 x 公里,他們就會結束旅行。

在啟程之前,小 a 想知道兩個問題:

1.對於乙個給定的 x=x0,從哪乙個城市出發,小 a 開車行駛的路程總數與小 b 行駛的路程總數的比值最小(如果小 b 的行駛路程為 0,此時的比值可視為無窮大,且兩個無窮大視為相等)。

2 .  如果從多個城市出發,小 a 開車行駛的路程總數與小 b 行駛的路程總數的比值都最小,則輸出海拔最高的那個城市。對任意給定的 x=xi和出發城市 si,小 a 開車行駛的路程總數以及小 b 行駛的路程總數。

【資料範圍】對於100%的資料,有1≤n≤100,000,1≤m≤10,000,-1,000,000,000≤hi≤1,000,000,000,0≤x0≤1,000,000,000,1≤si≤n,0≤xi≤1,000,000,000,資料保證 hi互不相同。

總思想:二分

f[i][j]表示從節點i出發,a和b總共走2^j步的一些狀態,比如:

f[i][j][0]表示2^j後,a總共走的距離

f[i][j][1]表示2^j後,b總共走的距離

f[i][j][2]表示2^j後,a+b總共走的距離

f[i][j][3]表示2^j後,到達的節點座標

倍增方程f[i][j] = f[f[i][j-1][3]][j-1]   即從i出發,先走2^j-1步,到達點x,然後繼續走2^j-1步,總共走了2^(j-1)+2^(j-1)=2^j步。

這樣只要求出f[i][0]及f[i][1]就可以求出所有的f[i][j]。(這道題,f[i][0]有點特別,我這裡專指a走1步,所以是從f[i][1]推倒到f[i][j]的,而不是f[i][0]開始推倒)

接下來就是預處理了:如何快速求出每個點出發的最近點以及次近點?

按高度快排,同時記錄編號為i的城市,最後在快排序列的什麼位置。

假設這個排序序列是a1,a2,a3,…an。則,對於ai這個城市,如果所有編號i-2 ai-1ai+1 ai+2中的兩個。將這個4個城市進行判斷,得出解以後,其實這個城市ai已經沒用了,可以從序列中刪除以保證後面能也同樣處理。

所以我們只需將這個快排以後的序列儲存到鍊錶中,並且從編號小的點處理到編號大的點,邊處理邊刪除即可求出所有城市的最近點以及次近點。複雜度o(4n)

預處理複雜度o(4n+nlogn),完全可以接受並且很理想。

接下來考慮如何處理問題1:

其實很簡單,遍歷所有城市,計算出以城市i出發行走x0距離,小a及小b行走的距離差即可。

假設行走x0距離,ab總共需開t次車,則即是如何快速求這個t的問題,因為求出來以後直接用之前通過倍增得到的狀態陣列就可以算出需要的距離差了。

不妨將t看做乙個二進位制數,則就是如何快速從t轉成二進位制的問題了,因為f陣列就是存了二進位制下,二進位制各位的狀態。所以logn的代價內就能求出這個t,因為最多就是走n步。所以第乙個問題的複雜度是o(nlogn)

接下來考慮如何處理問題2:

第二問只是問題比較多而已啦,但是每個小問題和第一問沒什麼區別,而且複雜度更低。所以只需求解這個m個問題就行了,o(mlogn)。

NOIP2012提高組 開車旅行

這題倍增。當拿到a陣列時,我們便記錄他的位置併排個序 再用乙個陣列 然後,我們就將其變成乙個鍊錶的樣子。由於題目要求每次這能從左邊走到右邊,所以我們便從1開始列舉到n,ps luogu的也a了 上標 include include define ll long long define n 10001...

NOIP2012提高組 開車旅行

把ab各走一次算一步 f i j 表示i點跳2 j步走到的點 da i j 表示i點跳2 j步a走的路程 db i j 表示i點跳2 j步b走的路程 倒著掃一遍求從i點a走出一次走到的點toi,記錄da i 0 然後,我們把to i 和i連邊 2.倒著掃一遍求從i b走出一次走到的點t,再列舉所有i...

NOIP2012提高組 開車旅行

題目 洛谷p1081 vijos p1780 codevs1199。題目大意 有n座海拔高度不相同的城市 編號1 n 兩城市的距離就是兩城市海拔之差。規定每次只能從編號小的城市走到編號大的城市。現在有a和b開車旅行,a每次只開到離當前城市第二近的城市 必須是可以走的,且若兩個城市與該城距離相等,海拔...