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);
}