poj_2299 Ultra-QuickSort
2013-09-09 16:56
260 查看
原题链接:http://poj.org/problem?id=2299
分析:树状数组求逆序对+离散化。
1:因为“n distinct integers”,所以不会有重复的数,可以用hash的方式让数与下标一一对应。如题中样例。
输入的数 : 9 1 0 5 4
排序后的数: 0 1 4 5 9
对应的下标: 1 2 3 4 5
因为n < 500000,通过这样子的处理就可以使0 ≤ a[i] ≤ 999999999,最大下标为500000。。这就是离散化。
2:接着是树状数组求逆序对,我们从数组的后面开始插入到数组,那么数的逆序就是在之前插入的比它小的数,统计输出就好。
我的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
#define MAXN 500005
int C[MAXN];
int n;
int a[MAXN],b[MAXN];
void add(int i)
{
for(;i<=n;i+=i&(-i)) C[i]+=1;
}
int get_sum(int i)
{
int sum=0;
for(;i>0;i-=i&(-i)) sum+=C[i];
return sum;
}
int ser(int x)
{
int l=1,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[mid]==x) return mid;
else if(b[mid]>x) r=mid-1;
else l=mid+1;
}
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
memset(C,0,sizeof(C));
for(int i=1;i<=n;i++) scanf("%d",a+i);
memcpy(b,a,sizeof(a));
sort(b+1,b+1+n);
LL ans=0;
for(int i=n;i>=1;i--)
{//从数组的画面插数进树状数组,这样就可以找比它找插,且小得数有几个。
int ind=ser(a[i]); //有种hash的感觉,数与下标一一对应。
ans+= get_sum(ind); //得到有几个比ind小的数。
add(ind);
}
printf("%lld\n",ans);
}
return 0;
}
总结:第一次交,WA了,想了下,n最大是500000,在最坏情况下,所有的数都交换则需,n*(n+1)/2次,用int的话就溢出了,改为long long 。
分析:树状数组求逆序对+离散化。
1:因为“n distinct integers”,所以不会有重复的数,可以用hash的方式让数与下标一一对应。如题中样例。
输入的数 : 9 1 0 5 4
排序后的数: 0 1 4 5 9
对应的下标: 1 2 3 4 5
因为n < 500000,通过这样子的处理就可以使0 ≤ a[i] ≤ 999999999,最大下标为500000。。这就是离散化。
2:接着是树状数组求逆序对,我们从数组的后面开始插入到数组,那么数的逆序就是在之前插入的比它小的数,统计输出就好。
我的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
#define MAXN 500005
int C[MAXN];
int n;
int a[MAXN],b[MAXN];
void add(int i)
{
for(;i<=n;i+=i&(-i)) C[i]+=1;
}
int get_sum(int i)
{
int sum=0;
for(;i>0;i-=i&(-i)) sum+=C[i];
return sum;
}
int ser(int x)
{
int l=1,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[mid]==x) return mid;
else if(b[mid]>x) r=mid-1;
else l=mid+1;
}
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
memset(C,0,sizeof(C));
for(int i=1;i<=n;i++) scanf("%d",a+i);
memcpy(b,a,sizeof(a));
sort(b+1,b+1+n);
LL ans=0;
for(int i=n;i>=1;i--)
{//从数组的画面插数进树状数组,这样就可以找比它找插,且小得数有几个。
int ind=ser(a[i]); //有种hash的感觉,数与下标一一对应。
ans+= get_sum(ind); //得到有几个比ind小的数。
add(ind);
}
printf("%lld\n",ans);
}
return 0;
}
总结:第一次交,WA了,想了下,n最大是500000,在最坏情况下,所有的数都交换则需,n*(n+1)/2次,用int的话就溢出了,改为long long 。
相关文章推荐
- poj 2299 Ultra-QuickSort 离散化 + 树状数组
- POJ 2299 Ultra-QuickSort(归并排序 || 树状数组 || 线段树)
- poj_2299 Ultra-QuickSort(归并排序/树状数组 求逆序对)
- POJ 2299 Ultra-QuickSort 【树状数组 离散化 逆序对】
- POJ 2299 Ultra-QuickSort (归并排序、逆序数)
- poj 2299 Ultra-QuickSort
- POJ2299——Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort
- (应用排序算法编程7.2.2)POJ 2299 Ultra-QuickSort(使用归并排序来计算逆序对的个数)
- Mathematics:Ultra-QuickSort(POJ 2299)
- 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 (求逆序数)
- POJ2299——Ultra-QuickSort