您的位置:首页 > 产品设计 > UI/UE

poj-2299-Ultra-QuickSort-(树状数组and离散化)

2017-08-18 11:33 423 查看
Ultra-QuickSort

Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 62846 Accepted: 23420
Description


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
4000
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

Source

Waterloo local 2005.02.05

题意:给出序列,问经过最少多少次前后元素的交换使得这个序列为上升序列

题目还是求数组的逆序数,就是每个元素逆序数相加的和,不同的是这次元素值较大,0 ≤ a[i] ≤ 999,999,999,如果,直接开数组太费内存,所以这里用到了离散化的方法:即先排个序,再重新编号。如 a[] = {10000000, 10, 2000, 20, 300},那么离散化后 a[] = {5, 1, 4, 2, 3}。

代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define inf 0x3f3f3f
#define M 500010
int n,m,maxn;
int tree[M],b[M]; //b是离散化后的数组,其内部元素是a[i].v的重新赋值,但其相对大小未变
struct node{
int v,id;
bool operator <(const node& b) const
{
return v<b.v;
}
}a[M];
int lowbit(int i)
{
return i&(-i);
}
void add(int i)
{
while(i<=n)
{
tree[i]+=1;
i+=lowbit(i);
}
}
int sum(int i) //一定注意i>=1,切记i不能为0
{
int res=0;
while(i>0)
{
res+=tree[i];
i-=lowbit(i);
}
return res;
}
int main()
{
int i;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i].v);
a[i].id=i;
}
sort(a+1,a+n+1);
b[a[1].id]=1;
for(i=2;i<=n;i++)
{
if(a[i-1].v==a[i].v) b[a[i].id]=a[i-1].id;
else b[a[i].id]=i;
}
memset(tree,0,sizeof(tree));
ll cnt=0;
for(i=1;i<=n;i++)
{
cnt+=sum(n)-sum(b[i]); //离散化后元素最大值为n,sum(n)为元素总个数,而sum(b[i])为小于等于b[i]元素的个数,相减就是逆序数
add(b[i]);
}
printf("%I64d\n",cnt);
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: