1. 程式人生 > >藍橋杯 小朋友排隊(線段樹)

藍橋杯 小朋友排隊(線段樹)

二次 system ner 求逆 -s query 有一個 col pda

小朋友排隊

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

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

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

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

  如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關系的。
輸入格式
  輸入的第一行包含一個整數n,表示小朋友的個數。
  第二行包含 n 個整數 H1 H2 … Hn,分別表示每個小朋友的身高。


輸出格式
  輸出一行,包含一個整數,表示小朋友的不高興程度和的最小值。
樣例輸入
3
3 2 1
樣例輸出
9
樣例說明
  首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每個小朋友的不高興程度都是3,總和為9。
數據規模和約定
  對於10%的數據, 1<=n<=10;
  對於30%的數據, 1<=n<=1000;
  對於50%的數據, 1<=n<=10000;
  對於100%的數據,1<=n<=100000,0<=Hi<=1000000
思路:

  線段樹求逆序數

 1 package happynewyear;
 2 
 3 import java.util.Scanner;
4 5 class Node{ 6 int l; 7 int r; 8 int sum; 9 } 10 class tree{ 11 int pos; 12 } 13 public class Main{ 14 static int maxn = 1000010; 15 static Node [] e = new Node[maxn<<2]; 16 static tree [] trees = new tree[maxn<<2]; 17 static int [] a = new int[maxn];
18 static void build(int l,int r,int cur) { 19 e[cur] = new Node(); 20 e[cur].l = l; 21 e[cur].r = r; 22 e[cur].sum = 0; 23 if(l==r) { 24 return; 25 } 26 int mid = (l+r)/2; 27 build(l, mid, cur<<1); 28 build(mid+1, r, cur<<1|1); 29 } 30 static void pushup(int cur) { 31 e[cur].sum = e[cur<<1].sum+e[cur<<1|1].sum; 32 } 33 static int query(int pl,int pr,int cur) { 34 if(pl<=e[cur].l&&e[cur].r<=pr) 35 { 36 return e[cur].sum; 37 } 38 int mid=(e[cur].l+e[cur].r)/2; 39 int res=0; 40 if(pl<=mid) 41 res+=query(pl,pr,cur<<1); 42 if(pr>mid) 43 res+=query(pl,pr,cur<<1|1); 44 return res; 45 } 46 static void update(int tar,int cur) { 47 if(e[cur].l==e[cur].r) 48 { 49 e[cur].sum++; 50 return; 51 } 52 int mid=(e[cur].l+e[cur].r)/2; 53 if(tar<=mid) 54 update(tar,cur<<1); 55 else 56 update(tar,cur<<1|1); 57 pushup(cur); 58 } 59 public static void main(String[] args) { 60 Scanner cin = new Scanner(System.in); 61 int n = cin.nextInt(); 62 long res= 0; 63 build(0, maxn, 1); 64 for(int i=0;i<n;i++) { 65 a[i] = cin.nextInt(); 66 res += query(a[i]+1, maxn, 1); 67 update(a[i], 1); 68 } 69 System.out.println(res*res); 70 } 71 }

藍橋杯 小朋友排隊(線段樹)