【算法】重要逆序对-分治法

A:重要逆序对

总时间限制: 1000ms 内存限制: 256000kB
描述
给定N个数的序列a1,a2,…aN,定义一个数对(ai, aj)为“重要逆序对”的充要条件为 i < j 且 ai > 2aj。求给定序列中“重要逆序对”的个数。

输入
本题有多个测试点,每个测试点分为两行:第一行为序列中数字的个数N(1 ≤ N ≤ 200000),第二行为序列a1, a2 … aN(0 ≤a ≤ 10000000),由空格分开。N=0表示输入结束。
输出
每个测试点一行,输出一个整数,为给序列中“重要逆序对”的个数。
样例输入
10
0 9 8 7 6 5 4 3 2 1
0
样例输出
16
提示
请注意答案范围,如果使用printf输出long long类型,请用%lld

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

long long int count(vector<int>);

int main() {
	int N;
	cin >> N;
	while (N != 0) {
		vector<int> original_array;
		for (int i = 0; i < N; ++i) {
			int temp;
			cin >> temp;
			original_array.push_back(temp);
		}
		long long int res;
		res = count(original_array);
		cout << res << endl;
		cin >> N;
	}
}

long long int count(vector<int> oarray) {
	int n = oarray.size();
	if (n == 1) return 0;
	long long int res = 0, res1 = 0, res2 = 0, res3 = 0;
	int k = n / 2;
	vector<int> array1, array2;
	array1.resize(k);
	array2.resize(n - k);
	copy(oarray.begin(), oarray.begin() + k, array1.begin());
	copy(oarray.begin() + k, oarray.end(), array2.begin());
	vector<int>array11(array1);
	vector<int>array22(array2);
	sort(array1.begin(), array1.end());
	sort(array2.begin(), array2.end());
	int i = k - 1;
	int j = n - k - 1;
	while (true) {
		if (array1[i] <= (2 * array2[j])) {
			if (j > 0) {
				j--;
			}
			else {
				break;
			}
		}
		else {
			res3 += (j + 1);
			if (i > 0) {
				i--;
			}
			else {
				break;
			}
		}
	}
	res1 = count(array11);
	res2 = count(array22);
	res = res1 + res2 + res3;
	return res;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值