題目描述【題目分析】小 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,此時的比值可視為無窮大,且兩個無窮大視為相等)。如果從多個城市出發,小 a 開車行駛的路程總數與小 b 行駛的路程總數的比值都最小,則輸出海拔最高的那個城市。
對任意給定的 x=xi和出發城市 si,小 a 開車行駛的路程總數以及小 b 行駛的路程
總數。
倍增【**】
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
long
long inf=1000000000000000000ll;
const
long
double infd=1e60;
setlong> s;
maplong,long
long> mp;
struct nodet[5];
long
long h[100001],n,x0,q;
long
long a[100001],b[100001];
long
long fa[100001],fb[100001];
long
long va[100001][17],vb[100001][17];
long
long to[100001][17];
long
double ans1=1e60; long
long st1;
bool cmp(node a,node b)
} else
if (j==1) }
else
if (to[to[i][j-1]][j-1])
else
break;}}
}long
double cal1(long
long k,long
long x)
if (tb==0) return infd;
else
return (long
double) ta/ (long
double) tb;
}long
long ta,tb;
void cal(long
long k,long
long x)
}int main()
printf("%lld\n",st1);
scanf("%lld",&q);
while (q--)
}
P1081 開車旅行
p1081 開車旅行 排序優化 倍增 其實這道題一開始是一點也沒有頭緒,知道有高人指點了一下。說並不需要拘束於出發點和路徑長度,也就是問題1.2。不過乙個是固定路徑長度的詢問,另乙個是給定起點和路徑長度的詢問。所以問題一和問題二是可以使用乙個函式解決的,而且對於乙個城市來說,在不考慮路程的情況下,路...
P1081 開車旅行
傳送門 用倍增的思想 設 a i 表示a在 i 位置走一步到達的城市以及經過的路程 這裡我用結構體存a i b同理 設 f i j 表示從 i 位置出發,走 2 j 輪後到達的城市 一輪即ab各走一次 dis i j 表示從 i 位置出發,走 2 j 輪後經過總路程 da i j 表示從 i 位置出...
洛谷P1081 開車旅行 (Treap 倍增)
題目傳送門 題目分析 這題的兩個問其實是差不多的。第一問給出了x0,我們列舉起點s,就相當於變成了n個第二類詢問 s x0 1 s n 於是現在原問題變成了 給出 s,x 如何快速求s開始往下走不超過x距離時,a,b各走的距離?然後用資料結構預處理出a,b到達每乙個點之後會走哪個點,詢問時倍增往後跳...