P1081 開車旅行

2022-05-19 11:54:31 字數 1917 閱讀 2394

傳送門

用倍增的思想

設 a[ i ] 表示a在 i 位置走一步到達的城市以及經過的路程(這裡我用結構體存a[ i ]),b同理

設 f [ i ] [ j ] 表示從 i 位置出發,走 $2^j$ 輪後到達的城市(一輪即ab各走一次)

dis[ i ] [ j ] 表示從 i 位置出發,走 $2^j$ 輪後經過總路程

da [ i ] [ j ] 表示從 i 位置出發,走 $2^j$ 輪後a經過路程,db同理

然後就可以愉快地倍xia增gao了

但是現在有乙個問題,怎麼預處理出 a[ i ],b[ i ]

把城市編號從大到小加入 set,每次加入乙個城市前先求出 set 內離他最近的城市和第二近的城市

如果按高度排序後此高度排名為 i ,那麼最近的城市就在 i+1 和 i-1 中,次近的城市就在 i+1,i+2,i-1,i-2 中

這個可以用 lower_bound 求出

然後就可以搞了

思維難度不大,具體實現起來一堆細節噁心得一批

別忘了可能ab一人走一步走不了,但是a單獨可以多走一步的情況

關於題目的第乙個問題,如果b的路程為0,那麼就算a也為0 比值仍為inf

一定仔細看題目啊,很多細節啊

下面附上我那壓行嚴重的巨醜**:

#include#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;//

有些變數該開long long 果斷開

inline int

read()

while(ch>='

0'&&ch<='

9')

return x*f;

}const

int n=1e5+7

;const ll inf=5e9+7

;int

n,m,x0;

struct

node

inline

bool

operator

< (const node &tmp) const

}a[n],b[n],d[n];

//在a[i]b[i]中則是距離和編號

multiset s;

multiset

::iterator it;

int f[n][22

];ll dis[n][

22],da[n][22],db[n][22

];void

pre()

for(int i=1;i<=n;i++)//

預處理倍增陣列

else da[i][0]=db[i][0]=dis[i][0]=inf;//

不然設成inf

}

for(int k=1;k<=20;k++)

for(int i=1;i<=n;i++)

else da[i][k]=db[i][k]=dis[i][k]=inf;

}}int ansa,ansb;//

存ab的路程

inline void slove(int pos,int x)//

給定出發點和最大總路程求ab兩人的路程

if(x>=a[pos].h) ansa+=a[pos].h;//

最後一定要特判a單獨多走一步

}void slove_problema()//

處理第乙個問題

printf(

"%d\n

",pos);

}void slove_problemb()//

處理第二個問題

}int

main()

P1081 開車旅行

p1081 開車旅行 排序優化 倍增 其實這道題一開始是一點也沒有頭緒,知道有高人指點了一下。說並不需要拘束於出發點和路徑長度,也就是問題1.2。不過乙個是固定路徑長度的詢問,另乙個是給定起點和路徑長度的詢問。所以問題一和問題二是可以使用乙個函式解決的,而且對於乙個城市來說,在不考慮路程的情況下,路...

洛谷 P1081 開車旅行

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

P1081 開車旅行 倍增 (毒瘤題)

其實就是個大模擬。首先,根據題意,小a和小b從任意乙個城市開始走,無論 x 如何,其路徑是一定唯一的。顯然對於兩問都可以想出乙個 o n 2 的暴力,即直接一步一步地向右走。首先,我們當然需要知道a,b在每個城市的下一步如何走,記 nexta i nextb i 為a,b在 i 處時,下一步走到的城...