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;
}