POJ 2299(树状数组,离散化)

Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 52711 Accepted: 19317
Description


In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
9 1 0 5 4 ,


Ultra-QuickSort produces the output 
0 1 4 5 9 .


Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input


The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output


For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input


5
9
1
0
5
4
3
1
2
3
0
Sample Output


6
0
Source


Waterloo local 2005.02.05



题意:求逆序数


题解:可以将数字插入树状数组,每次统计比单前数字小的个数,我们将每个数字的权值设置为1,那么只要求在他前面数字的和就知道了,对应的逆序数格个数是i-sum(a[i]),这里使用树状 数组维护区间和

这一题由于数字范围过大,内存无法承受如此大的空间,我们可以看到n最多才5e5,所以最多有n个不同数字,离散化即可,这一题很诡异的是卡STL。。。。。可以使用数组去映射,记录下每个数字的原来位置,将数字按升序排序,这样再将原来的位置依次插入i,这样相对的大小规则不会发生变化,求得的逆序数也不会发生变化,这样就达到了节省空间的目的



#include<cstdio>  
#include<cstring>  
#include<cstdlib>  
#include<cmath>  
#include<iostream>  
#include<algorithm>  
#include<vector>  
#include<map>  
#include<set>  
#include<queue>  
#include<string>  
#include<bitset>  
#include<utility>  
#include<functional>  
#include<iomanip>  
#include<sstream>  
#include<ctime>  
using namespace std;

#define N int(6e5+10)  
#define inf int(0x3f3f3f3f)  
#define mod int(1e9+7)  
typedef long long LL;
int c[N], n;
int a[N];

struct  point
{
	int x, y;
	bool operator<(const point &x1)const
	{
		return this->x<x1.x;
	}
}node[N];


inline void add(int x)
{
	for (int i = x; i <= n; i += (i&(-i)))
	{
		c[i]++;
	}
}
inline int sum(int x)
{
	int res = 0;
	for (int i = x; i>0; i -= (i&(-i)))
	{
		res += c[i];
	}
	return res;
}
int main()
{
#ifdef CDZSC  
	freopen("i.txt", "r", stdin);
	//freopen("o.txt","w",stdout);  
	int _time_jc = clock();
#endif  
	int  x, y;
	while (~scanf("%d", &n))
	{
		if (n <= 0)break;
		LL ans = 0;
		for (int i = 1; i<=n; i++)
		{
			c[i] = 0;
			scanf("%d", &node[i].x);
			node[i].y = i;
		}
		sort(node + 1, node + 1 + n);
		for (int i = 1; i <= n; i++)
		{
			a[node[i].y] = i;
			c[i] = 0;
		}
		for (int i = 1; i <= n; i++)
		{
			add(a[i]);
			ans += (i - sum(a[i]));
		}
		printf("%lld\n", ans);
	}
	return 0;
}











你可能感兴趣的:(POJ 2299(树状数组,离散化))