Luogu P2345 奶牛集會

2022-04-08 05:42:35 字數 1440 閱讀 5669

傳送門

這道題可以用分治的方法解決。(lbgxld說是線段樹,但是我覺得分治快而且好寫...)

暴力列舉是$o(n^2)$,想要優化,就不能一對一對列舉,最好能用乙隻奶牛一次計算一群其他的貢獻。

這就需要考慮聽力$v$和座標大小$x$的關係,可以把它轉化為乙個二維偏序問題。

首先把聽力$v$從大到小排序,控制一維。

然後用歸併排序,按$x$從小到大排序。

因為左邊一半$(l,mid)$奶牛的$v$一定大於右邊的$(mid+1,r)$,那麼我們只計算左邊的每乙個對右邊的貢獻。

也就是說,只有當左邊的乙個奶牛加入歸併的陣列時,才分別統計座標比它小和比它大的貢獻。

對於左邊的乙個奶牛,設它的聽力為$vi$,座標為$xi$。

設$s1$為右邊所有$x$比$xi$小的的座標之和  (初始為0);

設$s2$為右邊所有$x$比$xi$大的的座標之和 (初始為$(mid+1,r)$的奶牛座標之和)。

歸併排序的過程,就是不斷選取$x$較小的奶牛加入歸併陣列中。

如果列舉到右邊的乙個奶牛,不統計貢獻;但要把$s1$加上它的$x$,$s2$減去它的$x$。

如果列舉到左邊的乙個奶牛,統計貢獻:

已經統計出了有幾隻奶牛的座標比$xi$小,而剩餘的比$xi$大,

要求座標差的絕對值,答案即為$[ (xi*比它小的個數-s1)+(s2-xi*比它大的個數) ]* vi$(因為這個$vi$一定大於所有右邊的)。

因為兩邊已經按$x$從小到大排好,所以左邊在$xi$之後的奶牛的座標一定比$xi$大,也一定能對已經被加入$s1$中的奶牛做出貢獻。

一開始我想直接按二維偏序的方法做,只記錄比當前座標小的奶牛的貢獻,也就是只用大的減小的,最後乘2。

但是這道題並不是嚴格的偏序問題,它除了求逆序對還要求順序對,這兩個數量之和顯然不是逆序對數量*2。

**如下

#include#include

#include

#include

#define mogeko qwq#include

#define int long long

using

namespace

std;

const

int maxn =1e6;

intn,ans;

struct

vx } a[maxn],b[maxn];

void cdq(int l,int

r) ans += a[i].v*((j-mid-1)*a[i].x - s1 + s2 - (r-j+1)*a[i].x);

b[k++] = a[i++];

} while(j <=r)

b[k++] = a[j++];

for(int i = l; i <= r; i++)

a[i] =b[i];

}main()

view code

奶牛集會 luogu p2345

題目描述 約翰的n 頭奶牛每年都會參加 哞哞大會 哞哞大會是奶牛界的盛事。集會上的活動很多,比如堆乾草,跨柵欄,摸牛仔的屁股等等。它們參加活動時會聚在一起,第i 頭奶牛的座標為xi,沒有兩頭奶牛的座標是相同的。奶牛們的叫聲很大,第i 頭和第j 頭奶牛交流,會發出max xi xj 的音量,其中vi ...

luogu P2345 奶牛集會 排序 樹狀陣列

題目描述 約翰的n 頭奶牛每年都會參加 哞哞大會 哞哞大會是奶牛界的盛事。集會上的活動很多,比如堆乾草,跨柵欄,摸牛仔的屁股等等。它們參加活動時會聚在一起,第i 頭奶牛的座標為xi,沒有兩頭奶牛的座標是相同的。奶牛們的叫聲很大,第i 頭和第j 頭奶牛交流,會發出max xi xj 的音量,其中vi ...

P2345 奶牛集會

約翰的n 頭奶牛每年都會參加 哞哞大會 哞哞大會是奶牛界的盛事。集會上的活動很多,比如堆乾草,跨柵欄,摸牛仔的屁股等等。它們參加活動時會聚在一起,第i 頭奶牛的座標為xi,沒有兩頭奶牛的座標是相同的。奶牛們的叫聲很大,第i 頭和第j 頭奶牛交流,會發出max xi xj 的音量,其中vi 和vj 分...