開車旅行 題解 NOIP2012提高組

2022-08-18 05:36:17 字數 1237 閱讀 6506

首先我們可以發現,兩個詢問都可以通過乙個子程式來求。

接著,如果每到乙個城市再找下乙個城市,顯然是行不通的。所以首先先預處理從每乙個城市開始,小a和小b要去的城市。預處理的方法很多,我用的是雙向鍊錶:按高度把城市排序,用雙向鍊錶把每個城市的相鄰的城市裡連起來,再從每個城市按雙向鍊錶往兩邊搜,如果搜到的城市在這個城市的西邊就刪掉,否則記錄。左右分別記錄兩個城市,排個序就可以的出小a和小b要去的城市了。

然後我們就可以發現這是一棵樹,所以倍增。

我們設g[i][j]指從i城市走j2輪走到的點(一輪指小a和小b各走一次,小a先走),fa[i][j]指指從i城市走j2輪的小a走過路程,fb[i][j]指指從i城市走j^2輪的小b走過路程。轉移顯然。

#include #include #include #include #include #include #include const long long maxlongint=2147483647;

using namespace std;

struct lyd

;lyd a[200000];

long long h[200000][2],c[200000][5][3],qu[200000][3],yh[200000],lf[3],n,m,tot,sum,num,g[150000][17],fa[150000][17],fb[150000][17];

double ans;

void q(long long l,long long r)

} if(i=0;i--) }

if(c[x][2][1]+k<=value) }

int main()

scanf("%lld",&qu[0][2]);

scanf("%lld",&m);

for(i=1;i<=m;i++)

q(1,n);

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

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

if(j!=0)

}j=i;

while(a[j].next!=0)

if(j!=0)

}for(j=1;j<=c[i][0][0];j++)

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

for(j=1;j<=log2(n);j++)

}ans=double(maxlongint);

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

cout

}

NOIp2012 開車旅行

傳送門 以後序列上的問題可以想一想倍增。s a i s b i sa i sb i sa i sb i 記錄在i ii這個位置讓a b a ba b開車到達的點。把a aa和b bb都跳一次稱為一輪。d is i j dis i j dis i j 表示從i ii跳2 j2 j 2j輪的總路程。p ...

Noip2012 開車旅行

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

NOIP2012 開車旅行

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