這一題最終要構造的序列顯然是乙個單峰序列
首先有乙個結論:乙個序列通過交換相鄰的元素,進行排序,最少的交換次數為該序列的逆序對個數
(該結論很久之前打表意外發現的,沒想到用上了。。。。。)
考慮如何構造這個單峰序列
首先最大的數肯定是該序列的峰,餘下的元素我們從大到小列舉,判斷將其加入到當前序列的左邊還是右邊。
將某個數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,...