题解 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;
}
posted @ 2020-04-29 13:05  Ciciiiii  阅读(114)  评论(0)    收藏  举报