• 【题解】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;
    }
  • 相关阅读:
    项目实施经历
    Windows操作系统对物理内存支持
    企业管理靠员工自觉只能是海市蜃楼
    局域网IP冲突问题
    为什么编程是独一无二的职业?
    用命令实现Win7远程桌面关机和重启
    RAID(Redundant Array of Independent Disk 独立冗余磁盘阵列)
    Win7破解密码说明
    SAN,NAS,DAS及iSCSI其架构之间区别
    微软原版 windows server 2003 sp2 R2 系列下载分享
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/12210701.html
Copyright © 2020-2023  润新知