题干:

问题描述

  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。

解题报告:

我就说嘛、、、过了70%,不可能是思路错误,,检查了半天发现最后的统计答案爆了longlong、、、气死我了。

这题的关键在于看到交换的条件是:只能交换相邻的两个元素。这就使得问题简单了很多。考虑到x这个数,假设最后肯定要被交换到对应的位置上,那么看最少需要被交换多少次,在看这个次数能否可以实现。不难发现,最少被交换的次数,就是和前面比他大的数字,并且和后面比他小的数字。所以求该数对应的逆序数就行了。那么这个次数能否实现呢?不妨这样想,只考虑第i个数,假设前面比他大的有x1个,后面比他小的有x2个,我们先想办法将他前面比他大的数都交换到他后面去,这样他移动的次数就肯定是x1,并且得到的这样一个状态肯定是在他本该在的位置的前面,然后我们再通过和后面的数字的交换让他回到原来的位置就可以了,这一套操作是x2次,所以总次数可以达到x1+x2次。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e6 + 5;
int a[MAX];
int c[MAX];
int lowbit(int x){return x&(-x);}
int query(int x) {
	int res = 0;
	while(x>0) {
		res += c[x];
		x-=lowbit(x);
	}
	return res;
}
void update(int x,int val) {
	while(x<MAX) {
		c[x] += val;
		x+=lowbit(x);
	}
}
int ans1[MAX],ans2[MAX],ans[MAX];
int main()
{
	int n;
	cin>>n;
	for(int i = 1; i<=n; i++) {
		scanf("%d",a+i);
		a[i]++;
	}
	for(int i = n; i>=1; i--) {
		ans1[i] = query(a[i]-1);
		update(a[i],1);
	}
	memset(c,0,sizeof c);
	for(int i = 1; i<=n; i++) {
		ans2[i] = query(1000010) - query(a[i]);
		update(a[i],1);
	}
	for(int i = 1; i<=n; i++) ans[i] = ans1[i] + ans2[i];
	ll res = 0;
	for(int i = 1; i<=n; i++) {
		res += 1LL*(1+ans[i])*ans[i]/2;
	}
	printf("%lld\n",res);
	return 0 ;
}