[Codeforces] 1324-D Pair of Topics

鸽了Div3,抱着维持手感的心态直接做D题,结果被自己菜到....
题意是给你两个长度n数组,让你计算有多少对(i,j)满足ai+aj>bi+bj(i<j)

一开始想到二分,写了一半想不清楚怎么同时处理值和序号的大小关系,

于是又开始想树状数组。。因为有例题是用树状数组计算区间内比x小的数有多少,但是由于数据值太大,此方法不行。

正解是先不管下标关系,直接计算对于位置i有多少位置j满足bj-aj<ai-bj (上面的式子变形)

这个问题就用二分解决就行了,然后减去i=j的情况

并将结果减半就得到i<j的情况,

此题还要注意结果会爆int,不然wa12.....

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=2e5+10;
ll n,ans=0;
ll a[N],b[N],dif[N];
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>n;
    ll cnt=0;//满足不等条件的i=j的个数
    for(ll i=1;i<=n;i++) cin>>a[i];
    for(ll i=1;i<=n;i++)
    {
        cin>>b[i];
        dif[i]=b[i]-a[i];
        if(a[i]>b[i]) cnt++;
    };
    sort(dif+1,dif+n+1);
    for(ll i=1;i<=n;i++)
    {
        ll x=a[i]-b[i];
        ll j=lower_bound(dif+1,dif+n+1,x)-dif-1;//全数组范围内计算小于ai-bi的个数
        ans+=j;
    }
    ans-=cnt;
    cout<<ans/2<<endl;//结果应只包含i<j的
    return 0;
}
原文地址:https://www.cnblogs.com/Andrew-aq/p/12483798.html