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 output0 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
一开始想着用树状数组,每次输入的时候求比这个数大的数的总和就好了(ans+=i-read(x))后来竟然超时了;
经过了解,知道了必须要离散化
可是我还是不知道数据并不大,为什么要离散化
一,.解释为什么要有离散的这么一个过程?
刚开始以为999.999.999这么一个数字,对于int存储类型来说是足够了。
还有只有500000个数字,何必要离散化呢?
刚开始一直想不通,后来明白了,后面在运用树状数组操作的时候,
用到的树状数组C[i]是建立在一个有点像位存储的数组的基础之上的,
不是单纯的建立在输入数组之上。
二,怎么对这个输入的数组进行离散操作?
离散化是一种常用的技巧,有时数据范围太大,可以用来放缩到我们能处理的范围;
因为其中需排序的数的范围0---999 999 999;显然数组不肯能这么大;
而N的最大范围是500 000;故给出的数一定可以与1.。。。N建立一个一一映射;
(1)当然用map可以建立,效率可能低点;
(2)这里用一个结构体
struct Node
{
int val,pos;
}p[510000];和一个数组a[510000];
其中val就是原输入的值,pos是下标;
然后对结构体按val从小到大排序;
此时,val和结构体的下标就是一个一一对应关系,
而且满足原来的大小关系;
for(i=1;i<=N;i++)
a[p[i].pos]=i;
然后a数组就存储了原来所有的大小信息;
比如 9 1 0 5 4 ------- 离散后aa数组
就是 5 2 1 4 3;
ac 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
struct Node{
int v,id;
}node[500005];
int d[500005],t[500005],n,m,k;
bool cmp(Node a,Node b)
{
return a.v<b.v;
}
int lowbit(int k)
{
return (k&(-k));
}
void add(int pos,int v)
{
while (pos <= 100005)
{
d[pos]+=v;
pos += lowbit(pos);
}
}
int read(int k)
{
int sum=0;
while(k>0){
sum+=d[k];
k-=lowbit(k);
}
return sum;
}
int main(){
while(cin>>n)
{
if(n==0)break;
memset(d,0,sizeof(d));
for(int i=1;i<=n;i++)
{
cin>>node[i].v;
node[i].id=i;
}
sort(node+1,node+n+1,cmp);
for(int i=1;i<=n;i++) //离散化
{
t[node[i].id]=i;
}
long long ans=0;
for(int i=1;i<=n;i++)
{
add(t[i],1);
ans+=i-read(t[i]);
}
cout<<ans<<endl;
}
return 0;
}