Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 30129 | Accepted: 10760 |
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 sequence9 1 0 5 4 , Ultra-QuickSort produces the output0 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
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=500005; int n,c[maxn]; int b[maxn]; int lowbit(int x){ return x&(-x); } int Sum(int p){ int sum=0; while(p>0){ sum+=c[p]; p-=lowbit(p); } return sum; } void Update(int p,int val){ while(p<=n){ c[p]+=val; p+=lowbit(p); } } struct node{ int num,id; }a[maxn]; int cmp(node a,node b){ return a.num<b.num; } int main(){ while(scanf("%d",&n) && n){ memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); int i; for(i=1;i<=n;i++){ scanf("%d",&a[i].num); a[i].id=i; } sort(a+1,a+n+1,cmp); b[a[1].id]=1; for(i=2;i<=n;i++) if(a[i].id!=a[i-1].id) b[a[i].id]=i; else b[a[i].id]=b[a[i-1].id]; long long ans=0; for(i=1;i<=n;i++){ Update(b[i],1); ans+=Sum(n)-Sum(b[i]); } printf("%I64d\n",ans); } return 0; }
归并排序:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=500010; const int INF=0x3f3f3f3f; int n; long long ans; void Cal(int num[],int low,int mid,int high){ int len_L=mid-low+1; int len_R=high-mid; int* left=new int[len_L+2]; int* right=new int[len_R+2]; int i,j; for(i=1;i<=len_L;i++) left[i]=num[low+i-1]; left[len_L+1]=INF; for(j=1;j<=len_R;j++) right[j]=num[mid+j]; right[len_R+1]=INF; i=j=1; for(int k=low;k<=high;){ if(left[i]<=right[j]) num[k++]=left[i++]; else{ num[k++]=right[j++]; ans+=len_L-i+1; } } delete left; delete right; } void Mergesort(int num[],int low,int high){ int mid; if(low<high){ mid=(low+high)>>1; Mergesort(num,low,mid); Mergesort(num,mid+1,high); Cal(num,low,mid,high); } } int main(){ //freopen("input.txt","r",stdin); int num[N]; while(~scanf("%d",&n) && n){ for(int i=1;i<=n;i++) scanf("%d",&num[i]); ans=0; Mergesort(num,1,n); printf("%lld\n",ans); } return 0; }