首先我們可以發現,兩個詢問都可以通過乙個子程式來求。
接著,如果每到乙個城市再找下乙個城市,顯然是行不通的。所以首先先預處理從每乙個城市開始,小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 ...