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

2022-03-16 13:40:34 字數 1598 閱讀 5116

很好的逆序對板子題;

求的是(x1-x2)*(x1-x2)的最小值;

x1*x1+x2*x2-2*x1*x2

讓x1*x2最大即可;

可以證明將b,c陣列排序後,一一對應的狀態是最大的;

ac+bdac-ada*(c-d)a>b(???)

逆序對合併時一定要加等號!!要判斷q1是否超出mid!!!(爆零體驗);

歸併寫法

#include#include

#include

using

namespace

std;

const

int maxn=1e5+10

;const

int mo=99999997

;struct

node

b[maxn];

node c[maxn];

intn;

bool

cmp(node qw,node we)

inta[maxn];

inttmp[maxn];

intans;

void work_sort(int l,int

r)

else

}for(int i=l;i<=r;i++) a[i]=tmp[i];

}int

main()

for(int i=1;i<=n;i++)

sort(b+1,b+n+1

,cmp);

sort(c+1,c+n+1

,cmp);

for(int i=1;i<=n;i++)

work_sort(

1,n);

printf(

"%d\n

",ans);

return0;

}

view code

樹狀陣列寫法

#include#include

#include

using

namespace

std;

const

int maxn=1e5+10

;const

int mo=99999997

;struct

node

a[maxn];

node c[maxn];

intn;

intd[maxn];

bool

cmp(node qw,node we)

intb[maxn];

void add(int x,int

y)int query(int

x)int

ans;

intmain()

for(int i=1;i<=n;i++)

sort(a+1,a+n+1

,cmp);

sort(c+1,c+n+1

,cmp);

for(int i=1;i<=n;i++) d[a[i].id]=c[i].id;

for(int i=1;i<=n;i++)

printf("%d

",ans);

return0;

}

view code

洛谷P1966 火柴排隊 逆序對

題目鏈結 不算很難的一道題 首先要保證權值最小,不難想到一種貪心策略,即把兩個序列中rank相同的數放到同乙個位置 證明也比較trivial。假設 a 中有兩個元素 a,b b 中有兩個元素 c,d 然後分別討論一下當 a b 時 c 與 a 對應優還是與 b 對應優。化簡的時候直接對兩個式子做差。...

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

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

P1966 火柴排隊

題意 求兩個為n的序列貢獻值最小需要怎麼移動才能達到,移動 交換相鄰元素,貢獻值 ai bi 2。顯然可以猜出來,排序過後對應的最小。事實上也可以用反證法證明aac bd最小 我們令上面的序列不動,只動下面的序列,首先得到下面序列應該是怎麼樣的。用標號來標誌原來位置,排序過後,把對應位置賦值到陣列上...