zoukankan      html  css  js  c++  java
  • 蓝桥杯 小朋友排队(线段树)

    小朋友排队

    问题描述
      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 import java.util.Scanner;
      2 
      3 class Node{
      4     long l;
      5     long r;
      6     long sum;
      7     long sum2;
      8 }
      9 public class Main{
     10     static int maxn = 100010;
     11     static Node [] e = new Node[maxn<<2];
     12     static long [] a = new long[maxn];
     13     static long [] tmp = new long [maxn];
     14     static long [] res1 = new long [maxn];
     15     static long [] res2 = new long [maxn];
     16     static void build(long l,long r,int cur) {
     17         e[cur] = new Node();
     18         e[cur].l = l;
     19         e[cur].r = r;
     20         e[cur].sum = 0;
     21         e[cur].sum2 = 0;
     22         if(l==r) {
     23             return;
     24         }
     25         long mid = (l+r)/2;
     26         build(l, mid, cur<<1);
     27         build(mid+1, r, cur<<1|1);
     28     }
     29     static void pushup(int cur) {
     30         e[cur].sum = e[cur<<1].sum+e[cur<<1|1].sum;
     31     }
     32     static void pushup2(int cur) {
     33         e[cur].sum2 = e[cur<<1].sum2+e[cur<<1|1].sum2;
     34     }
     35     static long query(long pl,long pr,int cur) { 
     36         if(pl<=e[cur].l&&e[cur].r<=pr)
     37         {
     38             return e[cur].sum;
     39         }
     40         long mid=(e[cur].l+e[cur].r)/2;
     41         long res=0;
     42         if(pl<=mid)
     43              res+=query(pl,pr,cur<<1);
     44         if(pr>mid)
     45             res+=query(pl,pr,cur<<1|1);
     46         return res;
     47     }
     48     static long query2(long pl,long pr,int cur) {
     49         if(pl<=e[cur].l&&e[cur].r<=pr) {
     50             return e[cur].sum2;
     51         }
     52         long mid = (e[cur].l+e[cur].r)/2;
     53         long res = 0;
     54         if(pl<=mid)
     55             res+=query2(pl, pr, cur<<1); 
     56         if(pr>mid) 
     57             res+=query2(pl, pr, cur<<1|1);
     58         return res;
     59     }
     60     static void update(long tar,int cur) {
     61         if(e[cur].l==e[cur].r)
     62         {
     63             e[cur].sum++;
     64             return;
     65         }
     66         long mid=(e[cur].l+e[cur].r)/2;
     67         if(tar<=mid)
     68             update(tar,cur<<1);
     69         else
     70             update(tar,cur<<1|1);
     71         pushup(cur);
     72     }
     73     static void update2(long tar,int cur) {
     74         if(e[cur].l==e[cur].r)
     75         {
     76             e[cur].sum2++; 
     77             return;
     78         }
     79         long mid=(e[cur].l+e[cur].r)/2;
     80         if(tar<=mid)
     81             update2(tar,cur<<1);
     82         else
     83             update2(tar,cur<<1|1);
     84         pushup2(cur);
     85     }
     86     public static void main(String[] args) {
     87         Scanner cin = new Scanner(System.in);
     88         int n = cin.nextInt();
     89         build(0, maxn, 1);
     90         for(int i=0;i<n;i++) {
     91             a[i] = cin.nextInt();
     92             a[i] ++;
     93             //tmp[i] = a[i];
     94             res1[i] = query(a[i]+1, maxn, 1);
     95             //tmp += query(a[i]+1, maxn, 1);
     96             update(a[i], 1);
     97         //    
     98         }
     99         for(int i=n-1;i>=0;i--) {
    100             res2[i] = query2(0, a[i]-1, 1);        
    101             update2(a[i], 1);
    102         }
    103 //    =    System.out.println(tmp);
    104         /*for(int i=0;i<n;i++) {
    105             System.out.println("res1="+res1[i]+"res2="+res2[i]);
    106         }*/
    107         long ans = 0;
    108         for(int i=0;i<n;i++) {
    109             ans += (res1[i] + res2[i])*(res1[i] + res2[i] + 1)/2;
    110         }
    111         System.out.println(ans);
    112     }
    113 }
  • 相关阅读:
    .NET Interop 工具集
    关于正弦波的算法
    Windows Phone 系列 本地数据存储
    Xaml cannot create an instance of “X”
    Windows Phone 系列 使用 MVVM绑定时无法获取当前值
    Windows Phone 系列 应用程序图标无法显示
    Windows Phone 系列 WPConnect无法上网的问题
    Windows Phone 系列 使用 Windows Phone 保存铃声任务
    WP7.5提交应用
    Windows Phone 系列 动态删除ObservableCollection
  • 原文地址:https://www.cnblogs.com/1013star/p/10353226.html
Copyright © 2011-2022 走看看