Codeforces Round #627 (Div. 3) D. Pair of Topics

Codeforces Round #627 (Div. 3) D. Pair of Topics

D. Pair of Topics
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The next lecture in a high school requires two topics to be discussed. The i-th topic is interesting by ai units for the teacher and by bi units for the students.

The pair of topics i and j (i<j) is called good if ai+aj>bi+bj (i.e. it is more interesting for the teacher).

Your task is to find the number of good pairs of topics.

Input
The first line of the input contains one integer n (2≤n≤2⋅105) — the number of topics.

The second line of the input contains n integers a1,a2,…,an (1≤ai≤109), where ai is the interestingness of the i-th topic for the teacher.

The third line of the input contains n integers b1,b2,…,bn (1≤bi≤109), where bi is the interestingness of the i-th topic for the students.

Output
Print one integer — the number of good pairs of topic.

Examples
inputCopy
5
4 8 2 6 2
4 5 4 1 3
outputCopy
7
inputCopy
4
1 3 2 4
1 3 2 4
outputCopy
0

题意 :找i,j ai+aj>bi+bj

比赛想到的是 线段树求 逆序对 数比较大 还要离散化一下
比赛的时候 线段树 更新写错了 +=写成了+ 一直wa(菜哭)
赛后发现大佬用的都是 双指针 (菜是原罪啊)

式子变一下 ai-bi>bj-aj;
本人线段树写法:

#include<iostream>
#include<cstdio>
#include<map>
#include<math.h>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
ll sum[maxn<<2],la[maxn<<2];
void pushup(ll rt){
     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(ll l,ll r,ll rt){
 
     if(l==r){
        sum[rt]=0;
        return ;
     }
     ll m=(l+r)>>1;
     build(l,m,rt<<1);
     build(m+1,r,rt<<1|1);
     pushup(rt);
}
void update1(ll i,ll c,ll l,ll r,ll rt){
     if(l==r) {
        sum[rt]+=1;
        return;
     }
     ll m=(l+r)>>1;
     if(i<=m) update1(i,c,l,m,rt<<1);
     else update1(i,c,m+1,r,rt<<1|1);
     pushup(rt);
}
 
ll query(ll L,ll R,ll l,ll r,ll rt){
    ll s=0;
    if(L<=l&&R>=r) return sum[rt];
    ll m=(l+r)>>1;
    if(L<=m) s+=query(L,R,l,m,rt<<1);
    if(R>m)  s+=query(L,R,m+1,r,rt<<1|1);
    return s;
}
ll a[maxn],b[maxn],c[maxn];
map<ll ,ll >mp;
int main (){
    ll n;
    cin>>n;
    ll ans=0;
    for(int i=0;i<n;i++) scanf("%lld",&a[i]);
 
    for(int i=0;i<n;i++) scanf("%lld",&b[i]);
    
    ll k=0;
    for(int i=0;i<n;i++){
        c[k++]=a[i]-b[i];
    }
    for(int i=0;i<n;i++){
        c[k++]=b[i]-a[i];
    }
    sort(c,c+k);      //离散化
    ll temp=unique(c,c+k)-c;
    for(int i=0;i<temp;i++){
        mp[c[i]]=i+1;
    }                           //
    build(1,temp,1);
    for(int i=0;i<n;i++){
        ans+=query(mp[b[i]-a[i]]+1,temp,1,temp,1);
        update1(mp[a[i]-b[i]],1,1,temp,1);

    }
    printf ("%lld\n",ans);
}

双指针写法

#include<iostream>
#include<cstdio>
#include<map>
#include<math.h>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
ll a[maxn],b[maxn],c[maxn];
int main (){
    ll n;
    cin>>n;
    for(int i=0;i<n;i++) scanf("%lld",&a[i]);
    for(int i=0;i<n;i++){
        scanf("%lld",&b[i]);
        c[i]=a[i]-b[i];
    }
    sort(c,c+n);
    ll l=0,r=n-1,add=0;
    while(1){
        if(c[l]+c[r]>0){
            add+=r-l;
            r--;
        }
        else {l++;}
        if(l==r) break;
    }
    printf ("%lld\n",add);
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值