zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Java I/O的典型使用方式
    搜索--hiho 骑士问题
    编程之美--水王(找出出现超过1/2的数)
    深入理解java虚拟机之类文件结构以及加载
    【转载】Java JVM 运行机制及基本原理
    整数的划分总结(转)
    java静态方法和非静态方法
    mongodb 运行错误总结
    MongoDb windows环境安装,附百度云链接
    JAVA解析Json数据
  • 原文地址:https://www.cnblogs.com/F-Mu/p/12484761.html
Copyright © 2011-2022 走看看