NYOJ 117 求逆序数 【树状数组】或【归并排序】

来源:互联网 发布:centos ftp 编辑:程序博客网 时间:2024/05/16 06:40

原题链接:点击打开链接

【一】   利用 树状数组 离散化 之后求逆序数:

代码:

 #include<stdio.h>#include<string.h>#include<algorithm>#define N 1000000long long c[N+1],aaa[N+1];struct sb{int x;int y;}yi[N+1];bool cmp(struct sb t1,struct sb t2){    if(t1.x!=t2.x)   return t1.x<t2.x;    else       return t1.y<t2.y;}int lowbit (int a){return a&(-a);}void add(int a){while(a<N+1){c[a]+=1;a+=lowbit(a);}}int Sum(int a){int SUM=0;while(a>0){SUM+=c[a];a-=lowbit(a);}return SUM;}int main(){int a,b,n,m;scanf("%d",&n);while(n--){long long sum=0;memset(c,0,sizeof(c));scanf("%d",&m);for(a=1;a<=m;a++){scanf("%lld",&yi[a].x);yi[a].y=a;}        std::sort(yi+1,yi+m+1,cmp);//离散化。。。for(a=1;a<=m;a++)aaa[yi[a].y]=a; for(a=1;a<=m;a++){    add(aaa[a]);sum+=(a-1-Sum(aaa[a]-1));}printf("%lld\n",sum);     }}        
【二】 利用 归并排序 求逆序数:

代码:

 #include<stdio.h>#include<string.h>#define max 1000008long long count;long long a[max],t[max];void merge_sort(long long *a, long long x,long long y ,long long *t){if(y-x>1){long long m=x+(y-x)/2;//h划分long long p=x,q=m,i=x;merge_sort(a,x,m,t);//递归求解merge_sort(a,m,y,t);while(p<m||q<y){if(q>=y||(p<m&&a[p]<=a[q]))t[i++]=a[p++];else{t[i++]=a[q++];count+=(m-p);//计数。。}}for(i=x;i<y;i++)a[i]=t[i];}}int main(){ long long n,m;     scanf("%lld",&n);    while(n--)    {       scanf("%lld",&m);   memset(a,0,sizeof(a));   memset(t,0,sizeof(t));  long long b;  count=0;  for(b=0;b<m;b++)  scanf("%lld",&a[b]);  merge_sort(a,0,m,t);  printf("%lld\n",count);    }}        



原创粉丝点击