POJ 2299Ultra-QuickSort

来源:互联网 发布:网络计算机培训 编辑:程序博客网 时间:2024/05/01 10:34
题意:线段树求逆序对经典题目,需要离散处理,但是用stl处理的话会T,手动二分处理即可;
#include<algorithm>#include<iostream>#include<map>#include<set>#include<vector>#include<queue>#include<stack>#include<cstring>#include<cstdio>#define N 500005using namespace std;typedef struct node{int x;int y;int date;}node;bool cmp(int a,int b){return a>b;}node a[4*N];void built(int root,int first,int end){if(first==end){a[root].x=first;a[root].y=end;a[root].date=0;return ;}int mid=(first+end)/2;built(root*2,first,mid);built(root*2+1,mid+1,end);a[root].x=a[root*2].x;a[root].y=a[root*2+1].y;a[root].date=0;}void U(int root,int first,int end,int e){if(first==end){a[root].date++;return ;}int mid=(first+end)/2;if(e<=mid)  U(root*2,first,mid,e);else U(root*2+1,mid+1,end,e);a[root].date=a[root*2].date+a[root*2+1].date;}long long sum=0;void Q(int root,int first,int end,int l,int r){if(l<=first&&end<=r){sum+=a[root].date;return ;}int mid=(first+end)/2;if(l<=mid)  Q(root*2,first,mid,l,r);if(r>mid)  Q(root*2+1,mid+1,end,l,r);}long long b[N];long long c[N];long long e[N];long long p[N];int main(){int m;while(scanf("%d",&m)==1&&m!=0){for(int i=1;i<=m;i++){scanf("%d",&b[i]);p[i]=b[i];}sort(b+1,b+m+1,cmp);e[1]=b[1];int k=1;for(int i=2;i<=m;i++){if(b[i]!=b[i-1]){k++;e[k]=b[i];}}for(int i=1;i<=m;i++){int first=1;int end=k;while(first<=end){int mid=(first+end)/2;if(p[i]==e[mid]){c[i]=mid;break;}else if(p[i]<e[mid]){first=mid+1;}else{end=mid-1;}}}built(1,1,k);long long ans=0;  for(int i=1;i<=m;i++){  sum=0;  if(c[i]==1){  U(1,1,k,c[i]);  }  else{  Q(1,1,k,1,c[i]-1);  ans+=sum;  U(1,1,k,c[i]);}  }  printf("%lld\n",ans);}return 0;}

原创粉丝点击