CodeForces - 1324D Pair of Topics (分治+排序)

CodeForces - 1324D Pair of Topics

在这里插入图片描述在这里插入图片描述

题目大意:

这题大意ai+aj>bi+bj全在这个式子上,就问你满足的组合有几种,

题目分析:
整理一下,得到(ai-bi)+(aj-bj)>0 ,所以现在我们就只用做个差,然后找有几种组合就好了,
开始比较笨,tle了一发,后来才知道要分治一下,我们给做差后的数组排个序,每次找到比自己大的第一个数的下标,那么就可以很快的得到可以有几种组合

AC代码

#include<iostream>
#include<cmath>
#include <cstring>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e6;
long long  s1[maxn],s=0,b=0,ans,a1[maxn],b1[maxn];
int t;
int main(){
	while(scanf("%d",&t)!=EOF){
		s=0;b=0;ans=0;
		for(long long i=1;i<=t;i++){
			scanf("%lld",&a1[i]);
		}
		for(long long i=1;i<=t;i++){
			scanf("%lld",&b1[i]);
			a1[i]-=b1[i];
		}
		sort(a1+1,a1+1+t);
		for(int i=1;i<=t;i++){
			long long cnt=upper_bound(a1+i+1,a1+t+1,-a1[i])-a1;
			//printf("%lld  ",cnt);
			ans+=t-cnt+1;
			//printf("%lld\n",ans);
		}
		printf("%lld\n",ans);
	}
}

我又有个问题:
现在问题解决了

当我数组下标从0开始的时候,upper_bound 返回的就不是第一个大于查询数的位置,而变成了大于等于,结果输出就不对了,这是为什么啊,
问题代码

#include <cstring>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e6;
long long  s1[maxn],s=0,b=0,ans,a1[maxn],b1[maxn];
int t;
int main(){
	while(scanf("%d",&t)!=EOF){
		s=0;b=0;ans=0;
		for(long long i=0;i<t;i++){
			scanf("%lld",&a1[i]);
		}
		for(long long i=0;i<t;i++){
			scanf("%lld",&b1[i]);
			a1[i]-=b1[i];
		}
		sort(a1,a1+t);
		for(int i=0;i<t;i++){
			long long cnt=upper_bound(a1+i,a1+t,-a1[i])-a1;
			printf("%lld  ",cnt);
			ans+=t-cnt;
			printf("%lld\n",ans);//这里输出看看 
		}
		printf("%lld\n",ans),fflush(stdout);
	}
}

在这里插入图片描述这个,其实是我没注意,代码写错了,我传进upper_bound的是-a[o]比它大的是他自己没错,,所以注意:upper_bound(a1+i+1,a1+t+1,-a1[i])-a1 这里查找的时候,其实是排除了它自己,如果下标从0开始,那么应该写成upper_bound(a1+i+1,a1+t,-a1[i])-a1,a1+1+i是从后一个开始查,但是a1+t就可以了,这是他的上界
在这里插入图片描述所以修改后的从0开始的代码:

#include<iostream>
#include<cmath>
#include <cstring>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e6;
long long  s1[maxn],s=0,b=0,ans,a1[maxn],b1[maxn];
int t;
int main(){
	while(scanf("%d",&t)!=EOF){
		s=0;b=0;ans=0;
		for(long long i=0;i<t;i++){
			scanf("%lld",&a1[i]);
		}
		for(long long i=0;i<t;i++){
			scanf("%lld",&b1[i]);
			a1[i]-=b1[i];
		}
			
		sort(a1,a1+t);
		
		for(int i=0;i<t;i++){
			long long cnt=upper_bound(a1+i+1,a1+t,-a1[i])-a1;
			//printf("%lld  ",cnt);
			ans+=t-cnt;
			//printf("%lld\n",ans);//这里输出看看 
		}
		printf("%lld\n",ans),fflush(stdout);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值