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; }