Ultra-QuickSort 树状数组+离散化;

Ultra-QuickSort
Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 66796   Accepted: 25021

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
<center> 9 1 0 5 4 , </center>
Ultra-QuickSort produces the output
<center> 0 1 4 5 9 . </center>
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

             这里要注意的两个点就是离散化操作和怎样理解   ans += s - getsum(c[s]) + 1;这行代码所表达的内容;

             还有就是auto是c++ 14的内容,现在国内大多数oj是不支持的;(https://vjudge.net/problem/EOlymp-1303 在这里可以用auto)

             现在网上许多关于这道题的树状数组解答,基本没考虑过n个数中有同样的情况,他们大多是按照互不相同的n个数的条件来做的,可是这样考虑是不全面的,下面就是关于有相同的数的情况下的离散化操作;

             树状数组c开始的时候都初始化为0的,所以按照 9 1 0 5 4输入时,在进行离散化操作后也就会按照5 2 1 4 3的形式进行计算,5输入时,其他全是0,这时候getsum(5)=1;也就是说这时候不比5大的数的的数量之和是1(自己),因他而产生的逆序数就是0了;到输入4(离散化的4)的时候,c[1]=1,c[2]=2,c[3]=0,c[4]=1,所以getsum(4)=3,也就是在他之前的位置的不大于他的数的数量总和为3;这样依次进行计算即可。

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<cstdio>
using namespace std;
long long int m[500001];
int c[500001], n;
int tree[500001];
int lowbit(int x)
{
	return x&(-x);
}
int getsum( int x)
{
	long long int ans = 0;
	for (long long int s = x; s >= 1; s -= lowbit(s))
	{
//		cout << s << endl;
		ans += tree[s];
//		cout << s << " " << tree[s] << endl;
//		cout << ans << endl;
	}
	return ans;
}
void add( int x,  int d)
{
	for (long long int s = x; s <= n; s+=lowbit(s))
	{
		tree[s] += d;
	}
}
vector < long long  int > q;
void init()
{
	memset(tree, 0, sizeof(tree));
	memset(c, 0, sizeof(c));
	memset(m, 0, sizeof(m));
	q.clear();
}
int main()
{
	while (cin >> n&&n)
	{
		init();
		for (int s = 0; s < n; s++)
		{
			cin >> m[s];
			q.push_back(m[s]);
		}
		sort(q.begin(), q.end());
		auto siz = unique(q.begin(), q.end());
		for (int s = 0; s < n; s++)
		{
			c[s] = lower_bound(q.begin(), siz, m[s]) - q.begin() + 1;
		}
		long long int ans = 0;
		for (int s = 0; s < n; s++)
		{
			add(c[s], 1);
			ans += s - getsum(c[s]) + 1;
	//		cout << s + 1 - getsum(c[s]) << endl;
		}
		printf("%lld\n", ans);
	}
	return 0;
}





全部评论

相关推荐

昨天 11:07
河南大学 Java
宇宙厂 测开 n*15
丘丘给个offer:有后选后
点赞 评论 收藏
分享
威猛的小饼干正在背八股:挂到根本不想整理
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务