标签:des style blog http color os
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 38588 | Accepted: 13903 |
Description
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