CodeForces Round#627 D. Pair of Topics

原题链接

题目D

题意

现在有两个数组a[1…n],b[1…n]。定义一个 g o o d good good 概念: a [ i ] + a [ j ] > b [ i ] + b [ j ] ( i < j ) a[i]+a[j]>b[i]+b[j](ia[i]+a[j]>b[i]+b[j](i<j) 。要求给出 g o o d good good 的数量。

思路

我们观察这个不等式,就是第 i i i 列的差和第 j j j 列的差,两者之和大于0。对于一个大于 0 0 0 的差(比如说是 a a a ),我们要知道有多少个差和 a a a 相加能满足 g o o d good good 的条件,所以这样的差必定要满足 > − a >-a >a 。对于小于 0 0 0 的差,思路是类似的。所以我们要找出每个差的对应 g o o d good good 的选择范围内有多少记录,求和就可以。
每一列的差我们可以在 O ( n ) O(n) O(n) 求出来, O ( n l o g n ) O(nlogn) O(nlogn)排序后遍历每个差,用 u p p e r _ b o u n d upper\_bound upper_bound 去框最小的下标,计数就可以。
想要不重复计数的话,可以只遍历大于 0 0 0 的差,每次最大下标是前一个差的下标,只在前面的差中查找满足条件的个数。

代码
#include 
using namespace std;
const int MAX_N = 2e5+10;

int a[MAX_N];
int b[MAX_N];
int d[MAX_N];
int n;
long long ans;

int main(){
    cin >> n;
    for(int i=0;i<n;i++)    cin >> a[i];
    for(int i=0;i<n;i++){
        cin >> b[i];
        d[i]=a[i]-b[i];
    }
    sort(d,d+n);
    for(int i=0;i<n;i++){
        if(d[i]>0){
            int j=upper_bound(d,d+i,-d[i])-d;
            ans+=(i-j);
        }
    }
    cout << ans;
    return 0;
}

你可能感兴趣的:(CodeForces Round#627 D. Pair of Topics)