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,然后是n个乱序的数组序列,要求用冒泡排序的方法,要经过多少次交换才能变成升序排列?
解析:
大佬们说是求逆序数,逆序数我们会,但是这道题怎么变成逆序数的呢?
9 1 0 5 4
第一轮冒泡后:
1 0 5 4 9——交换4次,即9之后的四个数与9组成的逆序对的数量
第二轮冒泡后:
0 1 4 5 9——交换2次,即逆序对(1,0)和(5,4)
不难看出,一个数回到他升序的位置,即与他的逆序对中的另外一个数交换位置,有几对逆序对就交换几次,所以,就变成了对逆序数的求解!
然后这里a[i]与n的差距太大(0<=a[i]<=999999999,0<=n<=500000,如果我们开辟数组就要开辟很大的数组,但是输入却只有五十万个),所以要离散化处理!
离散化我就不详细讲了,我讲的也不行!_
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500050
using namespace std;
struct node{
int v,id;
};
int tree[N];
int V[N];
node book[N];
int n;
bool cmp(node a,node b)
{
return a.v<b.v;
}
int lowbit(int x)
{
return x&-x;
}
void updata(int x)
{
while(x<=n)
{
tree[x]+=1;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=0;
while(x>0)
{
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
long long sum;
while(scanf("%d",&n)&&n)
{
sum=0;
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++)
{
scanf("%d",&book[i].v);
book[i].id=i;
}
sort(book+1,book+n+1,cmp);
for(int i=1;i<=n;i++)
{
V[book[i].id]=i;
}
for(int i=1;i<=n;i++)
{
sum+=i-query(V[i])-1;
updata(V[i]);
}
printf("%I64d\n",sum);
}
return 0;
}
注意:
这里输出格式要用%lld(391ms)或者%I64d(375ms).