poj2299——Ultra-QuickSort
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.
Ultra-QuickSort produces the output
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
题意:
给定一个长度为n(n<=500000)的序列a,如果只允许进行比较和交换相邻两个数的操作,求至少需要多少次交换才能把a从小到大排序。
Solution:
容易发现每次交换和比较相邻的两个数使序列有序,就是冒泡排序,而冒泡排序的最少操作数就是序列中的逆序数对的个数,所以本题转换为求序列中的逆序对的个数。于是就可以用树状数组求啦。由于本题数据较大,所以我们需要对数值离散化,然后排序,按倒序update并getsum求在它更新之前有多少个数在其前面,详细见我的树状数组详解的博客。
代码:
#include<bits/stdc++.h> #define il inline #define ll long long using namespace std; const int N=500005; int aa[N],c[N],n; struct node{ int v,order; }a[N]; il bool cmp(node a,node b){return a.v<b.v;} il void update(int t,int v) { while(t<=n){ c[t]+=v; t+=(t&-t); } } il int getsum(int t) { int sum=0; while(t){ sum+=c[t]; t-=(t&-t); } return sum; } il int gi() { int a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-')x=getchar(); if(x=='-')x=getchar(),f=1; while(x>='0'&&x<='9')a=a*10+x-48,x=getchar(); return f?-a:a; } int main() { while(1){ n=gi(); if(!n)return 0; memset(c,0,sizeof(c)); for(int i=1;i<=n;i++)a[i].v=gi(),a[i].order=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++)aa[a[i].order]=i; ll ans=0; for(int i=n;i>0;i--)update(aa[i],1),ans+=getsum(aa[i]-1); printf("%lld\n",ans); } }
PS:~蒟蒻写博客不易,转载请注明出处,万分感谢!~