https://codeforces.com/gym/104857/problem/E
本來想卡常,後來發現O(m2n2)怎麼看都感覺不太對勁哈哈哈哈
所以查了一下,發現曼哈頓距離可以用距離貢獻度來看
字首和計算曼哈頓距離
xi右側的座標數量為n-i,那麼這些座標與xi的距離之和為:右側座標的累加和減去xi乘以(n-i)。
我們可以透過維護一個字首和陣列來有效計算這些累加和,從而避免對每個座標進行雙重迴圈的計算。
具體步驟如下:
排序座標:先將所有座標按照從小到大排序。
計算字首和:遍歷座標,計算到當前座標為止的所有座標的累加值,儲存在字首和陣列中。
計算每個座標的貢獻:
對於每個座標xi,其對總距離的貢獻可以透過字首和快速得到。具體來說:
對於左側的座標,使用字首和直接獲得x1到xi-1的和。
對於右側的座標,使用總和減去字首和得到xi+1到xn的和。
累加計算結果:將所有座標的貢獻累加起來,得到總的曼哈頓距離。
這種方法的時間複雜度主要是排序的O(n log n)和單遍歷的O(n),因此總體效率是O(n log n),這比暴力方法的O(n^2)要有效得多。
然後出現了TLE,最佳化了一下
ll calculateDistanceContributions(const vector<int>& positions) { int size = positions.size(); ll sum = 0, totalSum = 0; for (int i = 0; i < size; ++i) { totalSum += (ll)positions[i] * i - sum; sum += positions[i]; } return totalSum * 2; // Multiply by 2 to count both sides }
還有就是讀入的時候需要
ios::sync_with_stdio(false); cin.tie(nullptr);