bzoj4240 有趣的家庭菜園 樹狀陣列

2022-05-03 19:09:10 字數 897 閱讀 2346

這一題最終要構造的序列顯然是乙個單峰序列

首先有乙個結論:乙個序列通過交換相鄰的元素,進行排序,最少的交換次數為該序列的逆序對個數

(該結論很久之前打表意外發現的,沒想到用上了。。。。。)

考慮如何構造這個單峰序列

首先最大的數肯定是該序列的峰,餘下的元素我們從大到小列舉,判斷將其加入到當前序列的左邊還是右邊。

將某個數x移動到峰的兩側,所需要的步數為min(左側>x的數的個數,右側>x的數的個數)。

感性理解的證明就是:若要移動到峰的左側/右側,在這個時候,比它大的數字已經移動到了它的右側/左側,總共會有(>x的數的的個數)個數,跨過這個數。

然後乙個樹狀陣列判斷下就沒了。

1 #include2

#define l long long

3#define m 300005

4#define lowbit(x) ((x)&(-x))

5using

namespace

std;67

int n,a[m]=;

8void add(int x,int k)

9int query(int x)

10struct

node

12 node(int iid,int xx)

13 friend bool

operator

<(node a,node b)

14}b[m];

1516

intmain()

22 sort(b+1,b+n+1

);23 l ans=0;24

for(int i=1,j;i<=n;)

29for(;i1

);30

}31 cout32 }

BZOJ4240 有趣的家庭菜園

給出乙個長度為n的序列,可以將相鄰的數交換位置,要求通過最少交換次數使得這個序列呈左邊段不遞減,右邊段不遞增 樹狀陣列 貪心 將每個數一開始的下標為原本的位置,最後得到的序列的逆序對數就是操作的次數 首先得到的序列肯定是最大的在中間,第二大的在旁邊。那麼就貪心放值,放的時候找左右兩邊能產生逆序對最少...

BZOJ 4240 有趣的家庭菜園

第一道樹狀陣列 用到了貪心的想法 交換的代價就是交換完之後的逆序對數 將所有ioi草從高到低放入 貪心判斷是放在左邊還是放在右邊 會爆int 也要考慮有兩棵ioi草高度相同 include include include include using namespace std const int m...

bzoj 4240 有趣的家庭菜園 樹狀陣列

隨手寫了一發rank1什麼鬼。因為4239有點繁瑣,就先跳過去了。然後看完這道題目就懵逼了。o o 但是仔細想想會發現對於一棵草,它的移動是不會影響到比它更高的草的,因此我們可以從小到大移動草,並且貪心地移動到較小的一邊,換句話說令f i,j,k 表示i j中比k大的數的個數,那麼對於某一棵草 x,...