码迷,mamicode.com
首页 > 编程语言 > 详细

P1908 逆序对——归并算法

时间:2020-01-19 00:40:15      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:amp   记录   今天   cin   nbsp   iostream   个数   string   names   

先吐槽


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

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

 

思路

  归并两个数组时,对于第二个数组的元素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;
}

P1908 逆序对——归并算法

标签:amp   记录   今天   cin   nbsp   iostream   个数   string   names   

原文地址:https://www.cnblogs.com/ZhengkunJia/p/12210701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!