APIO2015 八鄰旁之橋

2022-05-20 14:37:47 字數 2177 閱讀 4786

注意到 \(k = 1, 2\) 於是我們可以從簡單的 \(k = 1\) 開始入手。可以發現家和辦公室在同一邊的人不管建不建橋都是無所謂的,因此下面我們只需要考慮不在同一邊的人,假設橋的位置在 \(d\) 那麼答案可以簡單的表示為:

\[\sum\limits_ ^ n |s_i - d| + |t_i - d|

\]這可以看作是 \(2n\) 個在數軸上的點到 \(d\) 的距離,這是乙個很經典的問題,只需取這 \(2n\) 個點的中位數即可。

接下來再考慮 \(k = 2\) 的情況,如果我們想直接求出兩座橋的位置是很困難的,但是可以發現這樣一件事,在兩個相鄰的點之間任意乙個點建第一座橋的答案都將是一樣的,那麼這意味著我們第一座橋的有效位置只有 \(2n\) 個,那麼我們能否通過列舉這 \(2n\) 個位置來算出在第一座橋確定的情況下第二座橋最優的位置呢?可以發現這也是乙個很困難的事情,因為每個點要在兩座橋之間走的距離取最小值,我們很難確定當前橋對所有人的影響。這時候感覺無路可走了,但注意到我們之前都是從橋來考慮對人的影響,我們不妨反過來,解決剛剛那個困難的問題,兩座橋中人會選擇哪座橋。手玩一些例子可以發現,貌似假如將每個人的 \(s_i, t_i\) 看作是一條線段,那麼他回選擇距離這條線段中點近的那座橋。證明分兩個端點和兩座橋的位置關係即可。

有了上面這個人選橋的最優方案,不難發現最終所有人(按中點從小到大排序)選橋的方案一定是左邊的人選一座橋,右邊的人選另一座橋。那麼左右兩邊橋的位置我們就可以使用 \(k = 1\) 的方法來求解了。但是中間的分界點還是難以確定,因此我們還需列舉中間的分界點。那麼我們怎樣快速計算答案呢?假設這 \(2n\) 個點的座標分別為 \(x_1 \cdots x_\),橋選在 \(d\),那麼答案的計算式應該是:

\[\sum\limits_ x_i - d + \sum\limits_ d - x_i

\]於是我們需要乙個能查詢一組數的中位數,查詢比某個數小的數有多少個,以及這些數的權值為多少的資料結構,權值線段樹是乙個好的選擇。

#includeusing namespace std;

#define ls (p << 1)

#define rs (p << 1 | 1)

#define mid (l + r) / 2

#define rep(i, l, r) for(int i = l; i <= r; ++i)

typedef long long ll;

const int n = 200000 + 5;

const ll inf = 10000000000000000;

ll ans;

char p[2], q[2];

int n, m, k, s, t, d[n];

struct tree

if(mid >= x) update(ls, l, mid, x, y, k);

if(mid < y) update(rs, mid + 1, r, x, y, k);

sum[p] = sum[ls] + sum[rs], cnt[p] = cnt[ls] + cnt[rs];

} ll query(int p, int l, int r, int k)

int find(int p, int l, int r, int k)

}t1, t2;

struct nodea[n], b[n];

int read()

while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}namespace s1

}namespace s2

void solve()

rep(i, 1, n) sr += a[i].l, sr += a[i].r;

rep(i, 1, n) t2.update(1, 1, tot, b[i].l, b[i].l, 1), t2.update(1, 1, tot, b[i].r, b[i].r, 1);

rep(i, 1, n)

printf("%lld", ans + (tmp == inf ? 0 : tmp)); }}

int main(), ++ans;

} n = num;

if(k == 1) s1 :: solve();

else s2 :: solve();

return 0;

}

APIO2015 八鄰旁之橋

傳送門 題目大意 兩條水平的直線,距離為 1 給定 n 對座標,座標是在某一條直線上的某乙個位置,你可以建立 k 豎直的直線 k leq 2 要使得每對座標只沿著直線移動從第乙個座標到第二個座標的距離和最小。題解首先可以求出在一對座標在同一條水平直線上的代價,對於需要跨越的,都經過了豎直直線的 1 ...

APIO2015 八鄰旁之橋

傳送門 這道題看起來十分的不可做 可能是我數學太差智商太低了orz。首先如果乙個人的家和辦公室在同一側那就完全不用考慮,把結果記下來就行。然後我們先考慮k 1的情況。因為只能建1座橋,那麼我們發現 除去過橋乙個單位長度不算 答案就是sigma abs ai x abs bi x 其中ai,bi表示區...

APIO2015 八鄰旁之橋

一條東西走向的穆西河將巴鄰旁市一分為二,分割成了區域 aa 和區域 bb 每一塊區域沿著河岸都建了恰好 10000000011000000001 棟的建築,每條岸邊的建築都從 00 編號到 10000000001000000000 相鄰的每對建築相隔 11 個單位距離,河的寬度也是 11 個單位長度...