Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 61630 Accepted: 22882
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
题意:给出一个长度为n的数列,你每一次可以随意交换其中两个数字的位置。问你至少交换几次,才能使得这个数列是个递增数列。
明显的计算逆序数,两个方法,归并排序/树状数组
归并:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
#define N 500010
int a[N];
int n;
long long ans;
void mery(int l,int r,int mid)
{
int i,j;
//mid=(l+r)/2;
i=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j])
{
i++;
}
else
{
j++;
ans+=mid-i+1;///统计逆序数
}
}
sort(a+l,a+r+1);
return;
}
void merysort(int l,int r)
{
if(l<r)
{
int mid=(l+r)/2;
merysort(l,mid);
merysort(mid+1,r);
mery(l,r,mid);
}
return;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
ans=0;
merysort(0,n-1);
printf("%lld\n",ans);
}
return 0;
}
树状数组:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
#define N 500010
struct node
{
int id,w;
}num[N];
int n,BIT[N];
int lowbit(int x)///预备函数定义一个Lowbit函数,返回参数转为二进制后,最后一个1的位置所代表的数值
{
return x&(-x);
}
int cmp(node a,node b)
{
return a.w>b.w;
}
void add(int i)
{
while(i<=n)
{
BIT[i]+=1;
i+=lowbit(i);
}
}
long long sum(int k)
{
int ans=0;
for(int i=k;i>0;i-=lowbit(i))
{
ans+=BIT[i];
}
return ans;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
memset(BIT,0,sizeof(BIT));
for(int i=0;i<n;i++)
{
num[i].id=i+1;
scanf("%d",&num[i].w);
}
sort(num,num+n,cmp);
long long ans=0;
for(int i=0;i<n;i++)
{
ans+=sum(num[i].id-1);
add(num[i].id);
}
printf("%lld\n",ans);
}
return 0;
}