Description
n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
Input
输入的第一行包含一个整数n,表示小朋友的个数。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
Output
输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。
Sample Input
3 3 2 1
Sample Output
9
Hint
【样例说明】
首先交换身高为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。
首先交换身高为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。
Source
蓝桥杯
对每个数字,求出前面比他大的数字个数+后面比他小的数字个数,就是需要该数字需要交换的次数
每个人的不开心度就是首项是1,尾项是交换次数,d=1的等差数列的和
所以就是对每个数字进行一次等差数列的求和:(a1+d)*an/2
所以我们的重点是统计每个数字需要交换的次数
开始想的是冒泡
但我们冒泡肯定会超时
所以采用树状数组
快很多!
每个人的不开心度就是首项是1,尾项是交换次数,d=1的等差数列的和
所以就是对每个数字进行一次等差数列的求和:(a1+d)*an/2
所以我们的重点是统计每个数字需要交换的次数
开始想的是冒泡
但我们冒泡肯定会超时
所以采用树状数组
快很多!
具体分析:
用一个计数数组,数组的下标存输入的数字,先从头开始遍历,出现一次就加一,输入一次就统计前面大于该数字的数出现的次数:当前数字的个数i-前面小于等于该数字的个数
所以树状数组和线段树都是可以的
code:
树状数组
没有离散化的代码:
#include<stdio.h> #include<iostream> #include<math.h> #include<string.h> #include<set> #include<map> #include<list> #include<math.h> #include<queue> #include<algorithm> using namespace std; typedef long long LL; #define INF 99999999 #define me(a,x) memset(a,x,sizeof(a)) int mon1[13]= { 0,31,28,31,30,31,30,31,31,30,31,30,31}; int mon2[13]= { 0,31,29,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]= { { 0,1},{ 0,-1},{ 1,0},{-1,0}}; int getval() { int ret(0); char c; while((c=getchar())==' '||c=='\n'||c=='\r'); ret=c-'0'; while((c=getchar())!=' '&&c!='\n'&&c!='\r') ret=ret*10+c-'0'; return ret; } void out(int a) { if(a>9) out(a/10); putchar(a%10+'0'); } #define max_v 1000005 LL a[max_v]; LL b[max_v]; LL c[max_v]; LL maxx; int n; int lowbit(int x) { return x&(-x); } void update(int x,int d) { while(x<=maxx) { c[x]+=d; x+=lowbit(x); } } int getsum(int x)//前面小于等于x的个数 { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x); } return