18.12.20 DSA 重要逆序对
Posted yalphait
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18.12.20 DSA 重要逆序对相关的知识,希望对你有一定的参考价值。
描述
给定N个数的序列a1,a2,...aN,定义一个数对(ai, aj)为“重要逆序对”的充要条件为 i < j 且 ai > 2aj。求给定序列中“重要逆序对”的个数。
输入
第一行为序列中数字的个数N(1 ≤ N ≤ 200000)。
第二行为序列a1, a2 ... aN(0 ≤a ≤ 10000000),由空格分开。输出输出一个整数,为给序列中“重要逆序对”的个数。
样例输入
10
0 9 8 7 6 5 4 3 2 1
样例输出
16
提示
如果使用printf输出long long类型,请用%lld
数据范围
对于40%的数据,有N ≤ 1000。
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 #include <stack> 5 #include <string> 6 #include <math.h> 7 #include <queue> 8 #include <stdio.h> 9 #include <string.h> 10 #include <set> 11 #include <vector> 12 #include <fstream> 13 #define maxn 200005 14 #define inf 999999 15 #define cha 127 16 #define eps 1e-6 17 using namespace std; 18 19 long long ans; 20 long num[maxn],tmp[maxn]; 21 int n; 22 23 void mysort(int left,int right) { 24 if (left == right)return; 25 int mid = (left + right) / 2; 26 mysort(left, mid), mysort(mid + 1, right); 27 int i = left, j = mid + 1, p = left, t = left; 28 while (i <= mid && j <= right) { 29 if (num[i] <= num[j]) 30 tmp[p++]=num[i++]; 31 else { 32 while (num[t] <= 2 * num[j]&&t<=mid) 33 t++; 34 if (num[t] > 2 * num[j]) 35 ans += mid - t + 1; 36 tmp[p++] = num[j++]; 37 } 38 } 39 while (i <= mid) 40 tmp[p++] = num[i++]; 41 while (j <= right) 42 tmp[p++] = num[j++]; 43 for (int i = left; i <= right; i++) 44 num[i] = tmp[i]; 45 } 46 47 void init() { 48 scanf("%d", &n); 49 for (int i = 1; i <= n; i++) 50 scanf("%ld", &num[i]); 51 mysort(1, n); 52 printf("%lld ", ans); 53 } 54 55 int main() { 56 init(); 57 return 0; 58 }
好像是把maxn写错了一直TLE……哭了
用同一个指针变量指示有点难想
以上是关于18.12.20 DSA 重要逆序对的主要内容,如果未能解决你的问题,请参考以下文章