火柴排隊(樹狀陣列求逆序對)

2022-03-14 12:18:18 字數 2241 閱讀 4042

2023年noip全國聯賽提高組

題目描述:

涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為:

,其中 ai表示第一列火柴中第 i 個火柴的高度,bi表示第二列火柴中第 i 個火柴的高度。

每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對 99,999,997 取模的結果。

輸入描述:

共三行,第一行包含乙個整數 n,表示每盒中火柴的數目。

第二行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第一列火柴的高度。

第三行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第二列火柴的高度。

輸出描述:

輸出共一行,包含乙個整數,表示最少交換次數對 99,999,997 取模的結果。

樣例輸入:

[sample 1]

4 2 3 1 4

3 2 1 4

[sample 2]

4 1 3 4 2

1 7 2 4

樣例輸出:

【樣例1說明】

最小距離是 0,最少需要交換 1 次,比如:交換第 1 列的前 2 根火柴或者交換第 2 列的前 2 根火柴。

【樣例2說明】

最小距離是 10,最少需要交換 2 次,比如:交換第 1 列的中間 2 根火柴的位置,再交換第 2 列中後 2 根火柴的位置。

【資料範圍】

對於 10%的資料, 1 ≤ n ≤ 10;

對於 30%的資料,1 ≤ n ≤ 100;

對於 60%的資料,1 ≤ n ≤ 1,000;

對於 100%的資料,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 2^31 - 1。

思路:

典型的數論題。給定了兩列火柴(兩個數列),根據題目要求,可將

拆分為許多獨立的個體:(a[i]-b[i])^2,拆開為:a^2+b^2-2ab,若使該式盡可能小,則2ab應盡可能大。那麼下一步就考慮如何使a[i]*b[i]盡可能大,根據排序不等式:反序和≤亂序和≤同序和 可得:a[i]*b[i]按照「同序」的方式排列起來是最大的,那麼什麼是同序?舉個例子:在有序數列1、2、3和有序數列4、5、6中,1*4,2*5,3*6就是同序,1*4+2*5+3*6就是同序和,所以應該先排序!那麼目前的這個問題就解決了,那麼解決這個問題是用來做什麼的呢?答案是:找到一種兩個數列之間的對應關係,求逆序對!使a中的第幾大對應b中的第幾大(這就是排序的目的),然後生成數列,在生成的數列中找出逆序對的個數,就是最終的答案了。

舉個例子:

火柴a:1 2 4 3

火柴b:1 4 2 3

顯然只需交換一步就出答案,答案為:1

如何得出:

把火柴a看為不動的,只移動火柴b。

排序之後:

火柴a為:1(1)、2(2)、3(4)、4(3),

同樣b為:1(1)、2(3)、3(4)、4(2)。

(括號中的為該數字在原數列中的id)

然後以排序後a中元素的id為下標,b中元素的下標為元素,生成數列x

x[1]=1 x[2]=3 x[4]=4 x[3]=2

也就是:x[4]=

x中逆序對為,僅此一對,所以ans=1.

完成!下面給出樹狀陣列求逆序對的**:

#include

#include

using namespace std;

const int

mod=99999997;

const int maxn=100010;

struct node

a[maxn],b[maxn];

int la[maxn],lb[maxn];

int n,ans,c[maxn],x[maxn];

bool cmp(node x,node y)

int lowbit(int x)

void add(int x)

int getsum(int x)

int main()

cout

return

0;}

樹狀陣列 P1966 火柴排隊 逆序對

1.求兩列之間的距離最小值 其實就是要求a 序列第 k 大的元素必須和序列 b 中第k大的元素的位置必須一樣 通俗的講就是aj與bj大的對應大的,小的對應小的,這樣相減的平方和才最小 2.火柴高度範圍是2的31次方,如果直接進行運算陣列會超,所以這裡需要離散化,用id來表示數字大小。3.現在得到兩個...

P1966 火柴排隊 逆序對(歸併,樹狀陣列)

很好的逆序對板子題 求的是 x1 x2 x1 x2 的最小值 x1 x1 x2 x2 2 x1 x2 讓x1 x2最大即可 可以證明將b,c陣列排序後,一一對應的狀態是最大的 ac bdac ada c d a b 逆序對合併時一定要加等號!要判斷q1是否超出mid 爆零體驗 歸併寫法 includ...

洛谷 P1966 火柴排隊(樹狀陣列求逆序)

涵涵有兩盒火柴,每盒裝有 nn 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 其中 a iai 表示第一列火柴中第 ii 個火柴的高度,b ibi 表示第二列火柴中第 ii 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交換,請你...