HPU1291 小朋友排队 【逆序数+树状数组】

1291: 小朋友排队

时间限制: 1 Sec  内存限制: 128 MB

提交: 2  解决: 1

[提交][状态][讨论版]
[Edit]

题目描述

n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。   每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。   如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。   请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。   如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

输入

输入的第一行包含一个整数n,表示小朋友的个数。  第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。1<=n<=100000,0<=Hi<=1000000。

输出

输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

样例输入

3 3 2 1

样例输出

9

提示

首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。

先顺序将数组中的数读入到树状数组T1中求出每个当前点跟左边的点构成的逆序点对数,再逆序将数组读入到树状数组T2中求出每个当前点跟它右边的点构成的逆序点对数。

#include <stdio.h>
#include <string.h>

#define maxn 1000010
typedef long long LL;

LL T1[maxn], T2[maxn], unhappy[maxn];
LL A[maxn], B[maxn], N; // B[]存储交换次数

LL lowBit(LL x) { return x & -x; }

void update(LL x, LL *arr) {
	for ( ; x < maxn; x += lowBit(x))
		++arr[x];
}

LL getSum(LL x, LL *arr) {
	LL sum = 0;
	for ( ; x; x -= lowBit(x))
		sum += arr[x];
	return sum;
}

int main() {
	// freopen("stdin.txt", "r", stdin);
	LL i, j;
	LL ret = 0;

	for (i = 1; i < maxn; ++i)
		unhappy[i] = unhappy[i-1] + i;

	scanf("%lld%lld", &N, &A[0]);
	update(A[0] + 1, T1);
	for (i = 1; i < N; ++i) { // 当前点跟左边的点产生的逆序对数
		scanf("%lld", &A[i]);
		update(A[i] + 1, T1);
		B[i] = i+1 - getSum(A[i] + 1, T1);
	}
	// for (i = 0; i < N; ++i)
	// 	printf("%lld..", B[i]);
	// printf("\n");
	for (i = N - 1; i >= 0; --i) { // 当前点跟右边的点产生的逆序对数
		update(A[i] + 1, T2);
		ret += unhappy[B[i] + getSum(A[i], T2)];
	}

	printf("%lld\n", ret);

	return 0;
}
时间: 2024-10-03 19:08:53

HPU1291 小朋友排队 【逆序数+树状数组】的相关文章

POJ_3067 Japan[ 逆序数 树状数组 or 归并排序)

传送门:POJ_3067 题目:n,m,k;左右两列数,数的范围分别1-n,1-m,然给k个连线. Sample Input 1 3 4 4 1 4 2 3 3 2 3 1 Sample Output Test case 1: 5 思路:逆序数 代码: //树状数组版 //块状数组 #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorit

hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1394 Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai

POJ 2299 Ultra-QuickSort(逆序数 树状数组)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 45960   Accepted: 16702 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

zoj 3157 Weapon 逆序数/树状数组

B - Weapon Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Description In World War 3, your countries' scientists have invented a special weapon. Assume that the enemy's city can be described by rectangular co

POJ - 2299 - Ultra-QuickSort = 归并排序 + 逆序对 / 树状数组

http://poj.org/problem?id=2299 求逆序对最简单的绝对不会是树状数组,一定是归并排序(认真),不过树状数组会不会快一点呢?理论上应该是树状数组快一点(假如不进行离散化). #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<map> #include<set

BZOJ 3295 [Cqoi2011]动态逆序对 树状数组套线段树

题意:链接 方法:树状数组套线段树 解析: 这题基本上写的都是什么CDQ点分治,主席树之类的,然而这我都并不会,所以写了一发平衡树套线段树想卡时卡过去,然而我并没有得逞,T的不要不要的,这里用平衡树套线段树的方法参见我的题解:排队.这道题比那道更要简单. 然后我就打算弃坑了~不过看140142做这道题做的热火朝天的,还是打算回来做一下,yy下树状数组套线段树,然后去看hz的题解,只看懂他写理论部分了,代码部分不知所云,所以还是还是得yy.引用理论部分. 删除某个数,只要统计它之前还存在的比它大的

BZOJ3295 CQOI2011 动态逆序对 树状数组套线段树

离线倒着做,每次加入一个节点后新增的逆序对数量就是其左边大于它的数的个数(左边数的总数-左边小于它的数的个数)+右边小于它的数的个数 用树状数组维护求和,对于树状数组中每个节点v所对应的区间线段树维护区间[l,r]中大于v的数的个数. 最后唯一的问题就是指针版线段树MLE-- #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <alg

求逆序对[树状数组] jdoj

求逆序对 题目大意:给你一个序列,求逆序对个数. 注释:n<=$10^5$. 此题显然可以跑暴力.想枚举1到n,再求在i的后缀中有多少比i小的,统计答案即可.这显然是$n^2$的.这...显然过不去,我们思考如何优化?显然,这里的有些过程是重复的.我们将这个序列设为a序列,对于两个1到n中的整数i<j,在j后面的数我们进行了多次重复枚举,我们思考如何优化.容易想到用一个桶来记录.只需要记录对于每一个数来讲,我后面有多少个数是比我小的,只需要将桶中的数累加即可.但是,我们必须记录是这个数之后的桶

【2018.12.15】【考试总结】【模拟+逆序对+树状数组+贪心+multiset】爆零之旅

这是我悲惨的接近爆零的一次考试,但是本蒟蒻不能放弃,还是要总结的QAQ 答题卡 [题目背景] 八月是个悲惨的月份.先不谈炎热的天气,对于新生来说,八月意味着军训: 而对于高二高三的同学来说,八月意味着开学考试.而考试就意味着改卷,改卷 也就意味着答题卡.不幸的是,学校读答题卡的机器的评分软件坏了,wyx 就被 老师要求写一个评分的程序. [问题描述] 软件需要读入学生的姓名.试题答案以及学生的答题卡信息. 学生姓名 学校的信息管理系统中存储了所有学生的姓名,一共 名学生.每个学生的 名字的组成只