Description

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
#include<stdio.h>
#include<string.h>
const int inf=100000000;
int a[1000000];
int l[1000000];
int r[1000000];
__int64 s=0;
void Merge(int left,int right,int mid)
{
int i,j,k,n1=mid-left+1;
int len1=0,len2=0;
for(i=left; i<=mid; ++i)
l[len1++]=a[i];
for(i=mid+1; i<=right; ++i)
r[len2++]=a[i];
l[len1]=inf;
r[len2++]=inf;
for(i=0,j=0,k=left; k<=right; ++k)
{
if(l[i]<=r[j])
{
a[k]=l[i];
i++;
}
else
{
a[k]=r[j];
j++;
s+=n1-i;
}
}
}
void merge_sort(int s,int t)
{
int m;
if(s<t)
{
m=(s+t)/2;
merge_sort(s,m);
merge_sort(m+1,t);
Merge(s,t,m);
}
}
int main()
{
int n,i;
while(scanf("%d",&n)&&n)
{
s=0;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
merge_sort(0,n-1);
printf("%I64d\n",s);
}
return 0;
}
今天第一次敲归并排序以前不会在BQ和JC的帮助下理解并解决了这个模版然后就是运用求逆序数的一个过程
在回溯的过程中每次看看中间值前面的数是否比后面大然后再合并
比如当回溯到下面的情况
2 5 8 3 4 9
在存入到5和4的时候因为5在4前面所以5后面的都是4的逆序数都要加上这样就求出来了
学习了线段树当然要用线段树来做一下了,但是在做的时候却遇到好多麻烦整整拖了一天才A出来,还是在JC的讲解下
思路懂但是网上有一个大神写的代码实在太深奥,看不懂,这个代码就是每次求出他前面比他小的个数用他在的位置去减一下就是它前面比他大的,还要注意离散化省时间和内存
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
struct node
{
__int64 id1,id2,k;
} q[600000];
int tree[600000<<1],a[600000];
bool cmp(struct node a,struct node b)
{
return a.k<b.k;
}
void update(int left,int right,int root,int a)
{
if(a<left||a>right)
return ;
if(a==right&&a==left)
{
tree[root]++;
return ;
}
int mid=(left+right)>>1;
update(left,mid,root<<1,a);
update(mid+1,right,root<<1|1,a);
tree[root]=tree[root<<1]+tree[root<<1|1];
}
int query(int left,int right,int root,int x,int y)
{
if(x>right||y<left)
return 0;
int mid=(left+right)>>1;
if(x<=left&&y>=right)
return tree[root];
return query(left,mid,root<<1,x,y)+query(mid+1,right,root<<1|1,x,y);
}
int main()
{
__int64 i , n , m , l , r , x , num ;
while(scanf("%I64d", &m) && m)
{
for(i = 0 ; i < m ; i++)
{
scanf("%I64d", &a[i]);
q[i].k = a[i] ;
q[i].id1 = i ;
}
sort(q,q+m,cmp);
int temp = -1 ;
n = 0 ;
for(i = 0 ; i < m ; i++)
{
if( q[i].k == temp )
q[i].id2 = n ;
else
{
q[i].id2 = ++n ;
temp = q[i].k ;
}
}
for(i = 0 ; i < m ; i++)
a[ q[i].id1 ] = q[i].id2 ;
memset(tree,0,sizeof(tree));
num = 0 ;
for(i = 0 ; i < m ; i++)
{
num += (i - query(1,n,1,1,a[i]));
update(1,n,1,a[i]);
}
printf("%I64d\n", num);
}
return 0;
}