poj-2299-Ultra-QuickSort-(树状数组and离散化)
2017-08-18 11:33
423 查看
Ultra-QuickSort
Description
![](http://poj.org/images/2299_1.jpg)
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
Sample Output
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;
}
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 62846 | Accepted: 23420 |
![](http://poj.org/images/2299_1.jpg)
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;
}
相关文章推荐
- POJ Ultra-2299 QuickSort 【离散化+树状数组】
- (POJ 2299)Ultra-QuickSort 树状数组求逆序对数 + 离散化
- poj2299 Ultra-QuickSort(树状数组求逆序数,离散化)
- POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ 2299 Ultra-QuickSort(树状数组+离散化处理)
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- POJ 2299 Ultra-QuickSort(归并排序,树状数组,离散化)
- 【Poj】-2299-Ultra-QuickSort(树状数组,离散化, 好)
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- POJ 2299 Ultra-QuickSort (树状数组 + 离散化)
- POJ:2299 Ultra-QuickSort(树状数组+离散化+技巧+求逆序对)
- POJ 2299 Ultra-QuickSort (树状数组 + 离散化)
- POJ 2299 Ultra QuickSort <树状数组+离散化 / 归并排序>
- poj 2299 Ultra-QuickSort (离散化,树状数组,逆序对)
- poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ 2299 Ultra-QuickSort(树状数组+离散化 或 归并排序求逆序)
- POJ 2299 Ultra-QuickSort (树状数组求逆序数 || 线段树 +离散化)
- POJ 2299 Ultra-QuickSort 【树状数组 离散化 逆序对】
- Poj 2299 - Ultra-QuickSort 离散化,树状数组,逆序对