30分求助,采用的分治算法

P1908 逆序对

an_yu @ 2022-09-29 21:58:05

#include <iostream>
using namespace std;
long long ans=0;
void merge(long long a[],int s,int m,int e){
    if(s>=e){
        return; 
    }
    int p1=s,p2=m+1,p=0,i;
    int tmp[e-s+1];
    while(p1<=m&&p2<=e){
        if(a[p1]>a[p2]){
            tmp[p++]=a[p1++];
        }else{
            tmp[p++]=a[p2++];
        }
    }
    while(p1<=m){
        tmp[p++]=a[p1++];
    }
    while(p2<=e){
        tmp[p++]=a[p2++];
    }//然后重新把tmp里的值赋给a,这就实现了从大到小的归并排序
    for(i=0;i<e-s+1;i++){
        a[s+i]=tmp[i];
    }
}
void mergesort(long long a[],int s,int e){
    if(s>=e){
        return;
    }else{
        int m=s+(e-s)/2;
        int i=s,j=m+1;
        mergesort(a,s,m);
        mergesort(a,m+1,e);
        while(i<=m&&j<=e){
            if(a[i]<a[j]){
                j++;
            }else{
                ans+=e-j+1;
                i++;
            }
        }
        merge(a,s,m,e);

    }
}
int main(){
    int n,i;
    scanf("%d",&n);
    long long a[n];
    for(i=0;i<n;i++){
        scanf("%lld",&a[i]);
    }
    mergesort(a,0,n-1);
    printf("%lld",ans);
    return 0;
}

代码如上,在第六个样例中标准答案为402002139 而我的输出为402002142 不知道问题出在哪里了。

另外为什么在归并的过程中,函数开头的边界条件如果设置成s>e就会出错,必须写成s>=e呢?

感谢大佬们肯抽出时间指点!


by bamboo12345 @ 2022-09-29 22:08:06

@an_yu 我觉得很有可能你把两数相等的时候算成逆序对了


by bamboo12345 @ 2022-09-29 22:08:40

@an_yu 第2个问题的话你想想s是不是永远不可能大于e?


by an_yu @ 2022-09-30 21:18:18

@bamboo123 好的,确实是您说的问题,我把两个数相等的时候也算成逆序对了。 第二个问题,您说的太有道理了哈哈哈哈。 谢谢!大佬国庆节快乐!


by an_yu @ 2022-09-30 21:19:34

@bamboo123 哈哈,点开您的个人主页一看,原来我上一个问题也是您给我解决的,太感谢大佬了!


by bamboo12345 @ 2022-09-30 21:20:08

国庆节快乐


by bamboo12345 @ 2022-09-30 21:20:37

哈哈哈那就是缘分了


|