zoukankan      html  css  js  c++  java
  • 5. 逆序对数

    问题:

    给一列数<a1,a2,......,an>,求它的逆序对,即有多少个有序对(i.j),使得i<j且ai<aj; n 可以高达106

    可以采用归并排序的思路

    首先将原问题可以分解为两个子问题:对原序列从中间一分为二,分解为两个子序列A,B
    两个子问题可以分别递归求解,求得的逆序数分别是na和nb
    合并:如果两个子序列A,B分别有序,那么可以在归并过程中求出数对(ai,bj){ai在A中,bj在B中}的逆序数,具体过程如下:
    如果ai<bj,则两者没有发生逆序,直接执行归并即可
    如果 ai>bj,则发生逆序,ai以及后面的元素都和bj构成逆序
    那么这个过程中求得的逆序数和na,nb的和就是原问题的解

    #include<iostream>
    using namespace std;
    int n;
    int *a;
    
    int fun(int l, int mid, int r) {
        int cnt = 0;
        for (int i = l; i <= mid; i++)
            for (int j = mid + 1; j <= r; j++)
                if (a[i] < a[j]) cnt++;
        return cnt;
    }
    
    int solve(int l, int r) {
        if (l == r) return 0;
        int mid = (l + r) / 2;
        return solve(l, mid) + solve(mid+1, r) + fun(l, mid, r);
    }
    
    int main() {
        scanf("%d", &n);
        a = new int[n];
        for (int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        cout << solve(0, n-1) << endl;
        delete[] a;
        return 0;
    }
  • 相关阅读:
    [CF1469D] Ceil Divisions
    [CF632D] Longest Subsequence
    [CF1215E] Marbles
    [CF689D] Friends and Subsequences
    [CF707D] Persistent Bookcase
    [CF10D] LCIS
    [CF713C] Sonya and Problem Wihtout a Legend
    [CF1114E] Arithmetic Progression
    [CF1404B] Tree Tag
    [CF710E] Generate a String
  • 原文地址:https://www.cnblogs.com/astonc/p/11662724.html
Copyright © 2011-2022 走看看