题解 CF1324D 【Pair of Topics】
Solution:
-
记录每个\(c_i=a_i-b_i\)。
-
因为要让老师赢,所以\(c_i+c_j>0\)
-
从小到大排序数组\(c\)。
-
显然,若\(c_i+c_j>0\),则\(c_i+c_{j+1}>0\)成立,所以二分查找合适的最小的j,记录ans=ans+n-j+1;
-
因为\(n\)最大为\(200000\),所以\(ans \le n^2\)会爆int,要开long long。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
int f=1,res=0;char c=getchar();
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){res=res*10+c-'0',c=getchar();}
return f*res;
}
const int maxn=2e5+5;
int a[maxn],b[maxn],c[maxn],n;
long long ans=0;
int main(){
n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) {
b[i]=read();
c[i]=a[i]-b[i];
}
sort(c+1,c+n+1);
for(int i=1;i<=n;i++){
int l=i+1,r=n,cnt=n+1;//寻找的j>i
while(l<=r){
int mid=l+r>>1;
if(c[i]+c[mid]>0) {
r=mid-1;
cnt=mid;
}
else l=mid+1;
}
ans=ans+n-cnt+1;
}
printf("%lld",ans);
return 0;
}

浙公网安备 33010602011771号