1 solutions

  • 0
    @ 2025-3-18 16:01:42

    nlognnlogn

    显然将两个数组从小到大排序以后可以得到的距离是最小的,那么我们记录原始的数组aabb,然后将aabb排序的做一个映射,类似于c[2]=3c[2]=3也就是本来是bb数组中的第二个位置其实放的是应该是第三个位置上的数,然后我们只需要得到cc数组1...n1...n的次数即可.

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> PII;
    #define x first
    #define y second
    const int N=1e5+10,P=99999997;
    int n;
    PII a[N],b[N];
    int c[N],p[N];//c是映射以后的数组,p是临时数组
    int merge_sort(int l,int r)
    {
        if(l>=r) return 0;
        int mid=l+r>>1;
        int res=(merge_sort(l,mid)+merge_sort(mid+1,r))%P;
        int i=l,j=mid+1,k=0;
        while(i<=mid&&j<=r)
        {
            if(c[i]<c[j]) p[k++]=c[i++];
            else
            {
                res=(res+mid-i+1)%P; //c[j]贡献的逆序对
                p[k++]=c[j++];
            }
        }
        while(i<=mid) p[k++]=c[i++];
        while(j<=r) p[k++]=c[j++];
        for(int i=l,j=0;i<=r;i++,j++) //还原数组
        {
            c[i]=p[j];
        }
        return res;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            a[i]={x,i};
        }
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            b[i]={x,i};
        }
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        for(int i=1;i<=n;i++) //映射初始排列
        {
            c[a[i].y]=b[i].y;
        }
        cout<<merge_sort(1,n);
        return 0;
    }
    
    
    • 1

    Information

    ID
    1101
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    1
    Accepted
    1
    Uploaded By