标签:des style blog http color os
| Time Limit: 7000MS | Memory Limit: 65536K | |
| Total Submissions: 38588 | Accepted: 13903 |
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 Input
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
这道题可以用线段树做,也可以用归并排序做。
线段树做法:
把数组 9 1 0 5 4
映射为1 1 1 1 1,
查找最小值0之前的1个数为2,并把0位置的值改为0,数组改变为1 1 0 1 1
再查找次小值1之前1个数为1;并把1位置的值改为0,数组改变为1 0 0 1 1
重复操作,得到结果为2+1+2+1=6;
线段树 1032MS
#include"stdio.h"
#include"stdlib.h"
#define N 500005
struct st
{
int x,id;
}b[N];
struct node
{
int l,r,s;
}f[N*3];
int cmp(const void*a,const void*b)
{
return (*(struct st*)a).x-(*(struct st*)b).x;
}
void creat(int t,int l,int r)
{
f[t].l=l;
f[t].r=r;
if(l==r)
{
f[t].s=1;
return ;
}
int temp=t*2,mid=(l+r)/2;
creat(temp,l,mid);
creat(temp+1,mid+1,r);
f[t].s=f[temp].s+f[temp+1].s;
}
int find(int t,int l,int r) //查找1到id之间1的个数
{
if(f[t].l>=l&&f[t].r<=r)
return f[t].s;
int temp=t*2,mid=(f[t].l+f[t].r)/2;
if(mid>=r)
return find(temp,l,r);
else if(mid<l)
return find(temp+1,l,r);
else
return find(temp,l,mid)+find(temp+1,mid+1,r);
}
void update(int t,int y) //把位置y的值改为0
{
if(f[t].l==f[t].r)
{
f[t].s-=1;
return ;
}
int temp=t*2,mid=(f[t].l+f[t].r)/2;
if(mid>=y)
update(temp,y);
else
update(temp+1,y);
f[t].s=f[temp].s+f[temp+1].s;
}
int main()
{
int i,n;
__int64 sum;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
{
scanf("%d",&b[i].x);
b[i].id=i;
}
creat(1,1,n); // 建树,把各个点都记为1;
b[0].x=-1;
qsort(b,n+1,sizeof(b[0]),cmp);
for(i=1,sum=0;i<=n;i++)
{
sum+=find(1,1,b[i].id);
sum--;
update(1,b[i].id);
}
printf("%I64d\n",sum);
}
return 0;
}
二:归并排序做法 2079MS
#include"stdio.h"
#define N 500005
const int inf=(int)1e10;
int a[N];
__int64 sum;
void count(int *a,int l,int mid,int r)
{
int i,j,k,n1,n2;
n1=mid-l+1;
n2=r-mid;
int *ll=new int [n1+1]; //申请一段大小为n1+1的内存
int *rr=new int [n2+1];
for(k=0;k<n1;k++)
ll[k]=a[l+k];
ll[k]=inf;
for(k=0;k<n2;k++)
rr[k]=a[mid+1+k];
rr[k]=inf;
for(i=j=k=0;k<r-l+1;k++)
{
if(ll[i]<=rr[j])
{
a[l+k]=ll[i];
i++;
}
else
{
a[l+k]=rr[j];
j++;
sum+=(n1-i);
}
}
delete ll; //释放内存空间
delete rr;
}
void mergesort(int *a,int l,int r)
{ //归并排序
if(l<r)
{
int mid=(l+r)/2;
mergesort(a,l,mid);
mergesort(a,mid+1,r);
count(a,l,mid,r);
}
return ;
}
int main()
{
int i,n;
while(scanf("%d",&n),n)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sum=0;
mergesort(a,0,n-1);
printf("%I64d\n",sum);
}
return 0;
}这个归并排序代码速度更快 360MS
#include"stdio.h"
#define N 500005
int a[N],b[N];
__int64 sum;
void mergesort(int l,int r) //数组从l到r,不包括右边界
{
if(r-l<=1)
return ;
int mid=(l+r)/2;
mergesort(l,mid); //不包括mid
mergesort(mid,r); //从mid开始,不含r
int i=l,j=mid,k=l;
while(i<mid||j<r)
{
if(j>=r||a[i]<=a[j]&&i<mid)
b[k++]=a[i++];
else
{
b[k++]=a[j++];
ans+=mid-i;
}
}
for(i=l;i<r;i++)
a[i]=b[i];
}
int main()
{
int i,n;
while(scanf("%d",&n),n)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sum=0;
mergesort(0,n);
printf("%I64d\n",sum);
}
return 0;
}
poj 2299 Ultra-QuickSort,码迷,mamicode.com
标签:des style blog http color os
原文地址:http://blog.csdn.net/u011721440/article/details/24723895