題目大意:
你給你的老妹出了一道題。在n個禮物中找出乙個,使之到其他禮物的距離之和最小。由於你老妹還沒學開根號,所以我們定義(x1,y1)(x2,y2)兩點間的距離為:|x2-x1|+|y2-y1|,為了證明老妹的答案是否是正確的,讓你求距離總和的最小值是多少。
30%的資料 n≤100
全部的資料n≤10^5
全部的資料 x i,yi≤10000
題解:
這題其實不難發現就是把每個點的距離總和求出來然後找乙個最小值min,不過直接列舉的話o(n^2)肯定會超時,所以我們考慮一下如何去優化:
我用的是排序+字首和:
①我們可以將x排序,排序時要將它原本的位置b[i]記錄,然後排序後,我們知道這時對於任意乙個xj有2種情況:
i>=j 則 它對xi的貢獻是xi-xj
j>i 則 它對xi的貢獻是xj-xi
這時候我們發現xi對ans[b[i]]的總貢獻是:
(i*xi-∑x[1..i])+(∑x[i+1..n]-(n-i)*xi)
然後求一段連續的區間的總和,我們可以用字首和o(n)去跑一遍,然後直接o(1)求
然後我們對y進行同樣的操作,最後得出來的ans[i],在裡面找乙個min。
時間複雜度:o(n)
var
sum,ans,a,b,c,d:array [0..100001] of longint;
i,j,n,min:longint;
procedure
qsort
(l,r:longint);
var i,j,mid:longint;
begin
if l>=r then
exit;
i:=l; j:=r;
mid:=a[(l+r) div
2]; repeat
while a[i]do inc(i);
while a[j]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
procedure
js;var
i:longint;
begin
for i:=1
to n do sum[i]:=sum[i-1]+a[i];
for i:=1
to n do
ans[b[i]]:=ans[b[i]]+(a[i]*i-sum[i])+((sum[n]-sum[i])-(n-i)*a[i]);
end;
begin
assign(input,'sister.in'); reset(input);
assign(output,'sister.out');rewrite(output);
readln(n);
for i:=1
to n do
begin
readln(a[i],c[i]);
b[i]:=i; d[i]:=i;
end;
qsort(1,n); js;
a:=c; b:=d;
qsort(1,n); js;
min:=maxlongint;
for i:=1
to n do
if min>ans[i] then min:=ans[i];
writeln(min);
close(input); close(output);
end.
P2700 逐個擊破
一開始以為題很難,當我坐下來認真讀題後,卻神奇地發現這道題很水 這和kruskal有什麼區別啊?於是我開開心心地十五分種敲完了 然後我就wa了 emmm 尷尬 一開始我對於每乙個點的no值都進行維護,時間複雜度特別高,於是就wa了qwq 後來我發現,其實一顆樹只要維護乙個no,即根結點的no即可,這...
題解 逐個擊破 luogu2700
現在有n個城市,其中k個被敵方軍團占領了,n個城市間有n 1條公路相連,破壞其中某條公路的代價是已知的。現在,告訴你k個敵方軍團所在的城市,以及所有公路破壞的代價,請你算出花費最少的代價將這k個地方軍團互相隔離開,以便第二步逐個擊破敵人。第一行包含兩個正整數n和k。第二行包含k個整數,表示哪個城市別...
SSL P1786 麻將遊戲
尋求最短路徑,但可越出平板 暫時性 相對其他的題目來說比較難,但只要處理好一些細節後,便會從複雜到簡單。我絕對不會說出ta是最小轉彎的 公升級版!include include include include define ll long long using namespace std inlin...