JOISC 2014 Day1 有趣的家庭菜園

2021-09-17 23:53:17 字數 1568 閱讀 5796

「joisc 2014 day1」有趣的家庭菜園

前置技能:樹狀陣列。

如果我們知道了目標序列,我們就可以構造乙個序列p,它的每乙個元素就是目標序列這一位置的元素在原序列的位置,那麼答案就是原位置序列[也就是]通過氣泡排序達到目標序列所需的交換次數目。而氣泡排序的交換次數就是p的逆序對的數量。

由於要滿足那兩個條件,那麼最後得到的序列一定是乙個單增,單減或是先單增,再單減。(不嚴格單增與單減,即可以相等)

故我們從大到小列舉ioi草,ioi草要麼位於之前放在之前的ioi草左邊,或者是右邊。

一種合法順序如下。(方框內寫的是放的順序)

然後每放一次,都用樹狀陣列求出放在左邊的增加的逆序對,再求出放在右邊的時候增加的逆序對。放在哪邊增加的逆序對少就放在哪邊。(這個貪心是正確的就是因為比他大的ioi草要麼都放在它的左邊,要麼都放在它的右邊)

當我們列舉到一堆高度相等的ioi草時怎麼放呢?首先對於乙個ioi草,記它放入序列左邊時增加的逆序對為lcost個,放在序列右邊增加的逆序對為rcost個,那麼如果他在原序列中的相對位置越大,它的lcost就會越大,它的rcost就會越小。於是我們可以把lco

st≤r

cost

lcost \leq rcost

lcost≤

rcos

t的ioi草放在序列左邊,另一些放在右邊。不難發現lco

st≤r

cost

lcost\leq rcost

lcost≤

rcos

t的ioi草在原序列中的相對位置會小於lco

st>rc

ostlcost > rcost

lcos

t>rc

ost的ioi草。又我們可以讓這些ioi草互相之間產生的逆序對數量為0(當這些ioi草放置後他們在原序列中的相對位置與目標序列的相對位置相同)。這樣子放肯定是最優的。實現方法就是先算出各自他們的答案,再在樹狀陣列上更新。

ac**:

#include

#include

#include

#define m 300005

#define lowbit(x) x&-x

using

namespace std;

int h[m]

;int n;

bool

cmp(

int x,

int y)

struct bin

void

add(

int x)

}int

sum(

int x)

return res;

}}b;

int id[m]

;int stk[m]

;void

solve()

else

}printf

("%lld\n"

,ans);}

intmain()

JOISC 2015 Day 1 卡片占卜

點此看題 可以把原來的陣列表示成差分陣列,那麼只有a 1 a b 1.a 1,a b 1.a 1,a b 1.這四個位置有值,我們要把所有值給消去。把操作理解為建邊,那麼找出兩個關鍵點的最短路就是消去這兩個關鍵點,那麼我們消去兩對關鍵點就可以了,有乙個特殊情況就是乙個點和n 1 n 1n 1相連,那...

JOISC 2020 Day1 建築裝飾 4

loj 考慮設 f 表示到了第 i 個位置,用了 j 個a,k 個b的可行性,打表發現對於 i,j 的 k 是連續的,所以考慮記錄 l 表示前 i 個位置用了 j 個a最少用多少個b,r 同理.最後輸出方案的時候一步一步的倒推即可.include include include include in...

NOIP2014day1 聯合權值

首先這是棵樹,那麼任意兩點間就只有一條路徑。要想值為2,那麼就需要兩個點連到同乙個點,即與同乙個點直接相連 那麼我們就可以列舉中間的點,然後遍歷它所有與其相連的點。另外總和權值可以這麼算 假如有兩個點 2ab a b 2 a2 b2 2ab a b 2 a 2 b 2 2ab a b 2 a2 b2...