Luogu 4998 訊號塔 題解報告

2022-10-10 08:30:12 字數 1726 閱讀 7718

給定乙個數軸,以及數軸上的 \(n\) 個點(這些點可能坐落在同一座標上),第 \(i\) 個點的座標為 \(a_i\) 。現在要在數軸上找 \(k\) 個點,第 \(i\) 個點的座標為 \(x_i\) 。求這 \(k\) 個點到原數軸上 \(n\) 個點距離和的最小值,即 \(min(\sum_^ \sum_^ |x_i - a_j|)\).

注:\(n,\ a_i \leq 10^6,\ k \leq n\)

首先,最容易想到的就是暴力模擬。迴圈列舉座標,對於每個座標,求出其到 \(n\) 個點的距離和。最後再將距離和公升序排列。時間複雜度 $o(an) = $tle

現在從兩個方向考慮優化:

減少列舉數量。也就是減少 \(x\) 的列舉數量。

減少計算過程。也就是降低求 \(x_i\) 到 \(a_j\) 距離和的複雜度。

而由於 \(x\) 與其他點的距離沒有方便計算的函式表示,所以減少列舉數量是不現實的(可能是因為我太弱了)

那麼怎樣減少計算過程呢??

設乙個點 \(x\) 到所有 \(a\) 的距離和為 \(s\)。

我們可以發現,如果 \(x\) 往前走乙個單位長度,那麼它與它前面點的距離就都會加一,與後面點的距離都會減一。

設 \(x\) 往前移動一位後, \(x\) 前面有 \(c\) 個點,後面有 \(n - c\) 個點。

那麼,距離就會變為:\(s + c - (n - c)\)。

所以,我們在列舉訊號站座標的時候,就可以順帶著將訊號站到其他點的距離用 \(o(1)\) 算出來

時間複雜度為 \(o(a)\)

**大概長這樣(由於空間有限,就不在這裡放了) wrong code

然後就驚喜的發現wa了乙個點 ...

發現我**中的錯誤是在一天之後了。我忽然發現,訊號站是有可能建在負數座標上的,舉個栗子:

數軸上點的座標為: \(a = [0, 0, 0, 0, 0]\)

我們要選擇5個訊號站。

那麼,最優解應該是 \(x = [0, 1, 2, -1, -2]\).

這樣,我們的訊號站就選到了負數點上。

這樣,我們只需要將訊號站列舉起點換成 \(-10^6\) (因為 \(k \leq 10^6\) 嘛)。由於陣列下標不能是負數,所以我們在陣列上加上乙個偏移量 \(delta\),讓陣列下標變成正數即可。

#include #include #include #include using namespace std;

typedef long long ll;

const int n = 1000010, m = n << 1;

ll f[m];

int p[n];

int delta = 1e6;

int n, m;

int map[n];

int main()

sort(p + 1, p + n + 1);

int l = 0, r = n;

f[0] = s;

for (int i = -1e6 + 1; i <= 1e6; i ++ )

sort(f, f + 2000000 - 1);

ll res = 0;

for (int i = 0; i < m; i ++ )

res += f[i];

printf("%lld\n", res);

return 0;

}

bzoj4998 星球聯盟

description 在遙遠的s星系中一共有n個星球,編號為1 n。其中的一些星球決定組成聯盟,以方便相互間的交流。但是,組成 聯盟的首要條件就是交通條件。初始時,在這n個星球間有m條太空隧道。每條太空隧道連線兩個星球,使得它們能 夠相互到達。若兩個星球屬於同乙個聯盟,則必須存在一條環形線路經過這...

BZOJ 4998 星球聯盟

題意 給一張無向圖,並不斷加邊 u,v 並詢問 u,v 是否位於同乙個雙聯通分量裡,若位於同一雙聯通分量,輸出這個雙聯通分量的 size 使用並查集 lct維護。有兩套並查集 s1是用來維護每個點歸屬哪乙個強連通分量,每個點的祖先是這個強連通分量的代表節點,同時代表節點儲存這個強連通分量的 size...

hdu 4998 矩陣表示旋轉

乙個旋轉變換可以轉化為乙個三維矩陣的變化 繞 x,y 旋轉角度r,執行十次,求等價旋轉點和角度 繞原點矩陣如下 由於是繞 x,y x1 x x0 cos0 y y0 sin0 x0 y1同理,那麼第三行前兩列即為x0 1 cos r y0 sin r 和y0 1 cos r x0 sin r 最後根...