zoukankan      html  css  js  c++  java
  • SGU 180

    题意

    给出一个数组 求这个数组的逆序数

    思路

    分治(nlogn):将问题划分为规模更小的子问题,递归地解决划分后的子问题,再将结果合并。
    考虑将数组a划分为两半得到b和c,于是a中的逆序对必然有三种情况:
    ①i,j都属于数列B的逆序对(i,j);
    ②i,j都属于数列C的逆序对(i,j);
    ②i属于B而j属于C的逆序对(i,j) .

    由于每次递归数列长度都会减半,所以递归深度为O(logn),而每一层总的操作都是O(n),所以总复杂度为O(nlogn)。

    // 树状数组(nlogn)

    AC代码(归并排序)

    白书《挑战程序设计竞赛》

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long ll;
    vector<int> A;
    
    ll mergecount(vector<int> &a)
    {
        int n = a.size();
        if(n<=1) return 0;
        ll cnt = 0;
        vector<int> b(a.begin(), a.begin()+n/2);
        vector<int> c(a.begin()+n/2, a.end());
        cnt += mergecount(b);
        cnt += mergecount(c);
        int ai = 0, bi = 0, ci = 0;
        while(ai < n){
            if(bi < b.size() && (ci == c.size() || b[bi] <= c[ci])){
                a[ai++] = b[bi++];
            }
            else {
                cnt += n/2 - bi;
                a[ai++] = c[ci++];
            }
        }
        return cnt;
    }
    
    int main()
    {
        int n, t;
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &t);
            A.push_back(t);
        }
        printf("%lld
    ", mergecount(A));
        return 0;
    }
    
  • 相关阅读:
    functools.partial偏函数
    python之路——模块和包
    异常
    递归函数
    内置函数和匿名函数
    列表推导式和生成器表达式
    迭代器和生成器
    Parentheses Balance
    poj1363 Rails
    hud1237 简单计算器
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740522.html
Copyright © 2011-2022 走看看