小朋友排隊 樹狀陣列

2021-10-02 14:52:31 字數 1505 閱讀 3123

問題 1439: [藍橋杯][歷屆試題]小朋友排隊

時間限制: 1sec 記憶體限制: 128mb 提交: 1083 解決: 170

題目描述

n  個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。

每個小朋友都有乙個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。

如果某個小朋友第一次被要求交換,則他的不高興程度增加1,如果第二次要求他交換,則他的不高興程度增加2(即不高興程度為3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增加k。

請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。

如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關係的。

樣例說明

首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每個小朋友的不高興程度都是3,總和為9。

資料規模和約定

對於100%的資料,1< =n< =100000,0< =hi< =1000000。

輸入輸入的第一行包含乙個整數n,表示小朋友的個數。 

第二行包含  n  個整數  h1  h2  …  hn,分別表示每個小朋友的身高。

輸出輸出一行,包含乙個整數,表示小朋友的不高興程度和的最小值。

樣例輸入

3 

3 2 1

樣例輸出

思路:要看出每乙個數交換的次數是前面比他大的數和後面比他小的數個數之和x,那麼不高興程度即為等差數列和x(x+1)/2。

這裡關鍵是怎麼求出前面比他大的數、後面比他小的數的 個數。這裡用到了樹狀陣列,我們把ai當作第ai個位置,建立樹狀陣列,然後這個位置的值是1,那麼我們就可以利用樹狀陣列求出字首和了。這樣就可以求出x。

注意ai初始時要加1,因為ai可能為0,樹狀陣列不能出現這樣的情況(即起點為1不能為0)。

#include#include#define rep(i,a,b) for(int i=a;i<=b;i++)

#define dep(i,a,b) for(int i=a;i>=b;i--)

#define ll long long

#include#include#include#includeusing namespace std;

const int maxn=1000000+6;

#define mod 1000000007

#define inf 0x3f3f3f3f

int a[maxn];

int c[maxn];

int lowbit(int x)

int getsum(int x)

return ans;

}void update(int x,int val)

}int b[maxn];

int main()

memset(c,0,sizeof(c));

dep(i,n,1)

rep(i,1,n)

cout<}

藍橋 小朋友排隊 樹狀陣列

思路 樹狀陣列處理逆序對 求前面有多少個數比當前這個大 正著插 求後面有多少個數比當前這個小 反著插 求出f陣列和b陣列即可 下面是ac include include include include include include include define ll long long defin...

acwing小朋友排隊(樹狀陣列)

考慮用樹狀陣列求解,簡單的暴力會超時。大概思路 每個數會和前面比它大的數交換,會和後面比它小的數交換,所以每個數交換的總次數為前面比這個數大的數的個數 後面比這個數小的個數,下面的 用b i 維護這個個數和。如何求呢?用樹狀陣列儲存每個數出現的次數。第一次正向遍歷,每次將資料出現的次數加入到樹狀陣列...

歷屆試題 小朋友排隊 樹狀陣列

歷屆試題 小朋友排隊 時間限制 1.0s 記憶體限制 256.0mb 問題描述 n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。每個小朋友都有乙個不高興的程度。開始的時候,所有小朋友的不高興程度都是0。如果某個小朋友第一次被要求交換,則他的不高興程度...