百练+重要逆序对归并排序,记得要有标记来减少循环扫描

来源:互联网 发布:淘宝上卖千岛片真的么 编辑:程序博客网 时间:2024/05/16 19:52
点击打开链接
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string>#include<cstring>#include<string.h>#include<math.h>#include<algorithm>#define inf 0x3f3f3f3f#define LL long longusing namespace std;int N=0;const int maxn=2e5+5;LL Arr[maxn]={0},temp[maxn]={0},sum=0;void MergeSort(LL Arr[], int left,int mid, int right){    int i=left,j=mid+1,len=right-left,index=0,flag_vis=-1;    while(i<=mid&&j<=right){        if(Arr[i]>Arr[j]){            if(flag_vis!=-1){                for(int flag=flag_vis;flag<=mid;flag++){                    if(Arr[flag]>2*Arr[j]){                        sum+=mid-flag+1;                        flag_vis=flag;                        break;                    }                }            }            else{                for(int flag=i;flag<=mid;flag++){                    if(Arr[flag]>2*Arr[j]){                        sum+=mid-flag+1;                        flag_vis=flag;                        break;                    }                }            }            temp[index++]=Arr[j]; j++;        }        else {            temp[index++]=Arr[i]; i++;        }    }    if(i>mid){        while(j<=right){            temp[index++]=Arr[j]; j++;        }    }    else{        while(i<=mid){            temp[index++]=Arr[i];i++;        }    }    for(int k=0;k<=len;k++){        Arr[left+k]=temp[k];    }}void Merge(LL Arr[], int left, int right){    if(left<right){        int mid=(left+right)/2;        Merge(Arr,left,mid);        Merge(Arr,mid+1,right);        MergeSort(Arr,left,mid,right);    }}int main(){    while(scanf("%d",&N)){        if(N==0) break;        for(int i=0;i<N;i++){            scanf("%lld",&Arr[i]);        }        sum=0;        Merge(Arr,0,N-1);        printf("%lld\n",sum);    }    return 0;}

原创粉丝点击