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

poj 2299 Ultra-QuickSort(归并排序 树状数组)

2015-01-29 20:46 375 查看
题意 :交换相邻的两个数来排序 最少交换几次

思路:

题意可以转化成求 数列中存在几个逆序数

可以看作冒泡排序 但是复杂度过高 可以用归并排序 和离散化的树状数组来完成

(注意 n<=5000000 所以ans 要用 长整型 )

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[5000000+100];
int t[5000000+100];
__int64 ans;
int l,r;
void merge(int x,int y)
{
if(y-x>1)
{
int m=x+(y-x)/2;
int p=x,q=m,i=x;
merge(x,m);
merge(m,y);
while(p<m||q<y)
{
if(q>=y||(p<m&&a[p]<=a[q])) t[i++]=a[p++];
else
{
if(p<m)
{
//printf("%d %d...\n",a[p],a[q]);
ans+=(m-p);
}
t[i++]=a[q++];
}
}
for(i=x;i<y;i++) a[i]=t[i];
// printf("%d %d %d\n",x,m,y);  for(i=0;i<r;i++) printf("%d ",a[i]);  printf("\n\n\n");
}
}
int main()
{
int n;
int i,j,k;
while(scanf("%d",&n),n)
{
ans=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
//l=0;r=n;
merge(0,n);
printf("%I64d\n",ans);
}
return 0;
}


树状数组

#include<cstdio>
#include<cmath>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
int n,c[500000+10],reflect[500000+10];
__int64 ans;

struct node
{
int val,pos;
};
node a[500000+10];

int cmp(node x,node y)
{
return x.val<y.val;
}
int lowbit(int x)
{
return x&(-x);
}
int sum(int x)
{
int ret=0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}

void add(int x)
{
while(x<=n)
{
c[x]+=1;
x+=lowbit(x);
}
}
int main()
{
while(scanf("%d",&n),n)
{
ans=0;
memset(c,0,sizeof(c));
int i,j;
for(i=1;i<=n;i++){ scanf("%d",&a[i].val); a[i].pos=i;}
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;i++) {reflect[a[i].pos]=i;}

for(i=1;i<=n;i++)
{
add(reflect[i]);
ans+=i-sum(reflect[i]);
printf("%I64d\n",ans);
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: