題目: 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。 現在將每盒中的火柴各自排成一列, 同一列火柴的高度互不相同,分析:兩列火柴之間的距離定義為: ∑(ai-bi)^2
其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。
每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對
99,999,997 取模的結果。
我們觀察距離的定義:
所以我們要求sigma(a[i]*b[i])的最大值
顯然讓a中最大的乘以b中最大的可以得到最大值,而我們同時交換兩個序列中的數字等價於乙個序列不動,交換另乙個序列中的數字
那麼我們就可以構造出乙個陣列c,c[i]代表a序列不動,b序列中的第i個數字要移動到位置c[i]上,此時c中的逆序對個數就是我們的最小交換次數
可以用歸併排序或者樹狀陣列求
**(樹狀陣列):
#include
#define ll long long
using
namespace std;
#define mod 99999997
long
long tr[
100010];
const
int n=
100005
;int n;
int bb[n]
;void
add(
int k,ll num)
}int
read
(int k)
return sum;
}struct node
aa[100010];
bool
cmp(node a,node b)
struct premu1
a[n]
;struct premu2
b[n]
;bool
cmpa
(premu1 x,premu1 y)
bool
cmpb
(premu2 x,premu2 y)
bool
cmpc
(premu2 x,premu2 y)
int sum[n]
;int
main()
for(
int i=
1;i<=n;i++
)sort
(a+1
,a+n+
1,cmpa)
;sort
(b+1
,b+n+
1,cmpb)
;for
(int i=
1;i<=n;i++
) b[i]
.tree=a[i]
.num;
sort
(b+1
,b+n+
1,cmpc)
;for
(int i=
1;i<=n;i++
) sum[i]
=b[i]
.tree;
memset
(tr,0,
sizeof
(tr));
for(
int i=
1;i<=n;i++
)sort
(aa+
1,aa+
1+n,cmp)
;int cnt =1;
for(
int i=
1;i<=n;i++
) ll summ =0;
for(
int i=
1;i<=n;i++
)printf
("%lld\n"
,summ)
;return0;
}
NOIP2013 火柴排隊(逆序對)
涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交換,請你通...
NOIP2013 火柴排隊
題目 分析 a中第幾大一定對應b中第幾大。ab同時移動相當於a移動,相對位置不變。所以,用c i 表示a i 需要移動到的 位置,求其中的逆序對。因為乙個每移動相鄰兩個元素相當於消除乙個逆序對。include include using namespace std const int tmax 10...
NOIP 2013 火柴排隊
題目描述 description 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 其中 ai表示第一列火柴中第 i 個火柴的高度,bi表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可...