CodeForces-1324D-Pair-of-Topics

题意

对于两个长度为\(n\)的数组\(a[]\)\(b[]\),找到有多少对\(i\)\(j\)\((i<j)\),满足\(a_i+a_j>b_i+b_j\)

分析

首先发现如果\(i\)\(j\)互换不影响不等式,因此对于\(i<j\)这个条件,仅仅是满足二元组\((i,j)\)\((j,i)\)只算一次

所以将数组打乱顺序后也只需找到所有的二元组\((i,j)\)即可

将不等式移项得到$$a_j-b_j>b_i-a_i$$对于第\(i\)项来说,我们要找到所有的\(j\)满足上述条件

因此选择将\(a_j-b_j\)排序

定义数组\(c[]\),有\(c[i]=a[i]-b[i]\)

方法一:

对于第\(i\)项,通过二分在\([i+1,n]\)找到最小的\(j\),满足该不等式,使用\(upper\_bound\)函数即可

则对于第\(i\)项,\(j\)~\(n\)都是满足的,将答案加上\(n-j+1\),如果没找到,则\(j=n+1\)\(upper\_bound\)已经满足)

#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
using namespace std;
const int maxn = (ll) 3e5 + 5;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f;

struct node {
    int a, b;
} a[maxn];

int c[maxn];

signed main() {
    start;
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i].a;
    for (int i = 1; i <= n; ++i)
        cin >> a[i].b, c[i] = a[i].a - a[i].b;
    sort(c + 1, c + n + 1);
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        int t = upper_bound(c + i + 1, c + n + 1, -c[i]) - c;
        ans += n - t + 1;
    }
    cout << ans;
    return 0;
}

方法二:

注意到排序后,随\(i\)递增,\(b_i-a_i\)递减,可以发现满足条件的\(j\)递减,因此可采取滑动区间的方式

\(now\)设置为\(n+1\)

每次循环若\(now>i\&\&c[now - 1] > -c[i]\),则\(now-1\)也满足不等式,将\(now\)减一

  • \(now>i\),同方法一,\(ans+=n-now+1\)
  • \(now=i\),即\([i+1,n]\)都满足条件,又由于\(j\)是递减的,所以对于后面的\(i\)\(now<i\),所以\([i+1,n]\)也满足条件,采取数列求和直接统计答案即可
#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define ls st<<1
#define rs st<<1|1
#define pii pair<int,int>
using namespace std;
const int maxn = (ll) 3e5 + 5;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f;

struct node {
    int a, b;
} a[maxn];

int c[maxn];

signed main() {
    start;
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> a[i].a;
    for (int i = 1; i <= n; ++i)
        cin >> a[i].b, c[i] = a[i].a - a[i].b;
    sort(c + 1, c + n + 1);
    int ans = 0;
    int now = n + 1;
    for (int i = 1; i <= n; ++i) {
        while (now > i && c[now - 1] > -c[i])
            --now;
        if (now == i) {
            ans += (n - i + 1) * (n - i) / 2;
            break;
        }
        ans += n - now + 1;
    }
    cout << ans;
    return 0;
}
posted @ 2020-03-13 10:22  幕无  阅读(160)  评论(0编辑  收藏  举报
1 博文导航目录