**開始天真的我以為這道題和運輸計畫是一樣的套路。於是寫了一發,debug後發現過了第乙個點,十分開心的交了一發,結果只過了第乙個點。後來發現這個並不是一樣的,因為修建黑洞之後路徑法變了,而運輸計畫沒有(樹上兩點間路徑唯一)。於是,第一題就成了題解題...
這道題顯然滿足二分性質。問題在與如何判斷合法。
首先,\(<=mid\) 的路徑肯定滿足,對於不滿足的路徑 \(l\) 到 \(r\),一定是在 \(x\) 和 \(y\) 處修建黑洞以後,\(l\) -> \(x\) -> \(y\) -> \(r\),且滿足不等式:
\[\left | l-x \right | + \left | r-y \right | <= mid
\]解得:
\[y\in\left [ l+r-mid+x,r-l+mid-x \right ]\left ( l>=x \right )
\]\[y\in\left [ r-l-mid+x,r+l+mid-x \right ]\left ( l
暴力的做法是列舉 \(x\),對於每乙個區間求出 \(y\) 的取值範圍,然後判斷是否有交集。
但這樣是 \(o(n^2)\) 的,需要優化。可以把區間分成兩部分,前一部分 \(l,後一部分 \(l>=x\),在兩個部分分別求交集,再兩部分的交集判斷是否有交集。這樣的話,前一部分的區間都有乙個增量 \(x\),交集就是 \(l+r-mid\) 的交集再加上 \(x\),對於 \(l+r-mid\) 的交集可以 \(o(n)\) 預處理。後一部分同理。前一部分預處理處理字首,後一部分字尾。
然後就可以 \(o(1)\) 判斷兩部分的交集是否有交集。**
#include using namespace std;
#define db double
#define ll long long
#define rg register
inline int gi()
const db pi = acos(-1.0);
const int n = 5e5+5, inf = 1<<30;
int n,m,cf[n],l1[n],r1[n];
struct range
}ra[n];
struct range
g[n];
inline bool check(rg int lim)
//預處理
p=cnt;
l1[n+1]=l2=-inf, r1[n+1]=r2=inf;
for (i=n; i; --i)
} //預處理對於每乙個x後一部分的解集
p=1;
for (i=1; i<=n; ++i)
//計算對於每乙個x前一部分的解集
if (l1[i] <= r1[i]+(i<<1) && l2+(i<<1) <= r2
&& !((r1[i] < l2) || (l1[i] > r2)))
return true; //判斷前後是否分別有解及兩部分是否有交集
} return false;
}int main()
sort(ra+1,ra+m+1);
l=0, r=n+1;
while (l <= r)
printf("%d\n",r+1);
return 0;
}
51Nod 1671 貨物運輸
acm模版 官方題解 首先我們需要注意到最重要的一點,所有運輸方案同時進行,我們只需要計算最後到達的方案的花費時間的最小值。所以我們需要考慮的是乙個極限情況,在這個極限情況下,其他運輸方案全部是在允許範圍內的。所以我們可以二分列舉這個極限情況,判斷所有方案是否都在這個極限內,在的話就繼續縮小極限,不...
51nod 1671 貨物運輸
公元2222年,l國發生了一場戰爭。小y負責領導工人運輸物資。其中有m種物資的運輸方案,每種運輸方案形如li,ri。表示存在一種貨物從li運到ri。這裡有n個城市,第i個城市與第i 1個城市相連 這裡1號城市和n號城市並不相連 並且從i號城市走到i 1號或者從i 1號走到i號需要耗費1點時間。由於高...
二分 曼哈頓距離 51Nod 1671 貨物運輸
題面在這裡 首先想到二分,設當前答案為 s 傳送門的兩個端點為x,y 則對於ti si s 的路徑,必須滿足 x si y ti s 這個可以理解為曼哈頓距離 而到某個定點 s i,ti 的曼哈頓距離相等的點構成的集合是乙個正方形 相當於判斷所有正方形是否有交 示例程式 include includ...