zoukankan      html  css  js  c++  java
  • 【题解】P1908 逆序对——归并算法

    先吐槽


    这题做了两天,昨天讲分治,老师用归并讲了一遍,今天又用树状数组讲了一遍

    归并不难,啊啊啊我居然才调出来

    思路

      归并两个数组时,对于第二个数组的元素a[c2],它与第一个数组中目前还没归到总数组里的元素形成逆序对

      c1,c2是指针,对于a[c2],它与a[c1..mid]构成逆序对,贡献{mid - c1 + 1}对

    注意

      ans开longlong,不然会WA一半!

      临时数组c开成全局变量,函数里放不下

    两种记录方式

      >函数不返回值,ans开成全局变量,在每次归并两个数组时增加对数

      >函数返回值,ans开在函数里,赋值递归两个分数组的返回值之和,再加上归并两个数组时的对数

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cmath>
    
    using namespace std;
    
    long long n , ans;
    int a[500005] , c[500010];
    long long back(int l , int r)
    {
      if(l == r)
        return 0;
      int mid = l + (r - l) / 2;
      long long ans = back(l , mid);
      ans += back(mid + 1 , r);
      int c1 = l , c2 = mid + 1 , top = l;//c[500010]太大,只能开全局 
      while (c1 <= mid && c2 <= r)
      {
        if(a[c1] <= a[c2])
          c[top++] = a[c1++];
        else
        {
          c[top++] = a[c2++];
          ans += mid - c1 + 1;
        }
    
      }
      while (c1 <= mid)
        c[top++] = a[c1++];
      while (c2 <= r)
        c[top++] = a[c2++];
      for (int i = l ; i <= r ; i++)
        a[i] = c[i];
      return ans;
    }
    
    int main()
    {
      cin >> n;
      for (int i = 1 ; i <= n ; i++)
      {
        cin >> a[i];
      }
      ans = back(1 , n);
      cout << ans << endl;
      return 0;
    }
  • 相关阅读:
    汇付 支付,痛苦的接入过程
    路由集合中已存在名为“ XXXX” 的路由
    博客目录
    (转载)为什么使用APP Bundle
    安卓基础:后台任务
    安卓基础:应用权限
    安卓资源的使用 二
    kotlin学习三:lambda 和内联函数
    kotlin学习二:函数
    kotlin学习一:基础语法
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/12210701.html
Copyright © 2011-2022 走看看