Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 68222 | Accepted: 25560 |
Description
![](https://i-blog.csdnimg.cn/blog_migrate/b3530eaa8fa98ef394d3639722240a8c.jpeg)
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
好久之前写的离散化,有点忘记了,现在拿出来以免以后忘记= =
比如输入
4
5 3 4 7
那么他们初始num分别是1,2,3,4
排序后
val 3 4 5 7
初始num 2 3 1 4
离散化num 1 2 3 4
那么放入树状数组插入的时候,先插入val为5的数(因为这是第一个输入的数字)
换句话说就是按照原num插入,但是插入的位置是离散化后的num
挺好理解的,就是一紧张容易混
树状数组代码如下
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<cstdio>
using namespace std;
const int maxn = 500005;
int tnum;
int c[maxn];
int Lowbit(int x)
{
return x&(-x);
}
void Add(int n,int val)
{
while(n<=tnum)
{
c[n]+=val;
n+=Lowbit(n);
}
}
int Query(int n)
{
int ans = 0;
while(n>0)
{
ans+=c[n];
n-=Lowbit(n);
}
return ans;
}
struct fom
{
int val;
int num;
} stu[500005];
int cmp(fom a,fom b)
{
return a.val<b.val;
}
int main()
{
int i;
while(~scanf("%d",&tnum)&&tnum)
{
memset(c,0,sizeof(c));
long long sum=0;
for(i=1; i<=tnum; i++)
{
scanf("%d",&stu[i].val);
stu[i].num=i;
}
sort(stu+1,stu+tnum+1,cmp);
map<int,int >newnum;
for(i=1; i<=tnum; i++)
{
newnum[stu[i].num]=i;
}
for(i=1; i<=tnum; i++)
{
int nowi=newnum[i];
Add(nowi,1);
sum+=i-Query(nowi);
}
printf("%lld\n",sum);
}
}
另外此题归并排序也可以过,之前没有初始化一直是WA吗,就以为归并还需不能过= =感觉自己像个zz
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 500005;
int a[N],tmp[N];
long long ans;
void Merge(int l,int m,int r)
{
int i = l;
int j = m + 1;
int k = l;
while(i <= m && j <= r)
{
if(a[i] > a[j])
{
tmp[k++] = a[j++];
ans += m - i + 1; ///只有此处为该题特有,其余为归并排序
}
else
{
tmp[k++] = a[i++];
}
}
while(i <= m) tmp[k++] = a[i++];
while(j <= r) tmp[k++] = a[j++];
for(int i=l; i<=r; i++)
a[i] = tmp[i];
}
void Merge_sort(int l,int r)
{
if(l < r)
{
int m = (l + r) >> 1;
Merge_sort(l,m);
Merge_sort(m+1,r);
Merge(l,m,r);
}
}
int main()
{
int n,T,tt=1;
while(~scanf("%d",&n)&&n!=0)
{
ans=0;
memset(a,0,sizeof(a));
memset(tmp,0,sizeof(tmp));
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
Merge_sort(0,n-1);
printf("%lld\n",ans);
}
return 0;
}