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
可能会很不好想,其实这道题就是让求逆序数,原本我用的树状数组谁知道T了,用了归并排序才AC
AC code:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 500000+5;
long long cnt = 0;
int a[MAXN],p[MAXN];
void Merge_Array(int first, int mid, int last)
{
int i=first, j=mid+1, k=first;
while(i<=mid && j<=last)
{
if(a[i] <= a[j])
p[k++] = a[i++];
else
{
p[k++] = a[j++];
cnt += j-k;
}
}
while(i <= mid)
p[k++] = a[i++];
while(j <= last)
p[k++] = a[j++];
for(int i=first; i<=last; i++)
a[i] = p[i];
}
void Merge_Sort(int first, int last)
{
if(first < last)
{
int mid = (first + last) >> 1;
Merge_Sort(first, mid);
Merge_Sort(mid+1, last);
Merge_Array(first, mid, last);
}
}
int Scan()
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
void Out(long long a)
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int main()
{
int n;
while(~scanf("%d",&n) && n)
{
cnt = 0;
for(int i=0; i<n; i++)
a[i] = Scan();
Merge_Sort(0, n-1);
Out(cnt);
puts("");
}
return 0;
}
TLE code:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 5e5+5;
int bit[maxn];
int maxx;
int pos;
struct node {
int val,id,v;
}ss[maxn];
int lowbit(int pos){
return (pos & (-pos));
}
void update(int pos,int val) {
while(pos <= maxx) {
bit[pos] += val;
pos += lowbit(pos);
}
}
int query(int pos){
int res = 0;
while(pos > 0) {
res += bit[pos];
pos -= lowbit(pos);
}
return res;
}
int cmp(node x,node y) {
return x.val<y.val;
}
int cmp1(node x,node y) {
return x.id<y.id;
}
int main(){
int t;
while(cin>>t && t)
{
map<int,int>mp;
memset(bit,0,sizeof(bit));
for (int i = 0;i<t;i++) {
scanf("%d",&ss[i].val);
ss[i].id = i;
}
sort(ss,ss+t,cmp); pos = 0;
for (int i = 0;i<t;i++) {
if ( !mp[ss[i].val] )
mp[ss[i].val] = ++pos;
ss[i].v = pos;
} maxx = pos;
sort(ss,ss+t,cmp1);
int sum = 0;
for (int i = 0;i<t;i++) {
sum += (query(maxx)-query(ss[i].v));
update(ss[i].v,1);
}
printf("%d
",sum);
}
return 0;
}