傳送門
用倍增的思想
設 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 處時,下一步走到的城...