第五题:T5最大的和
标签:二分查找
题意:给定两个序列
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
a_1,a_2,a_3,...,a_n
a1,a2,a3,...,an与
b
1
,
b
2
,
b
3
,
.
.
.
,
b
n
b_1,b_2,b_3,...,b_n
b1,b2,b3,...,bn,请从这两个序列中分别找一个数,要求这两个数的差不超过给定的数字
d
d
d,且这两个数字之和最大。(
1
<
=
n
<
=
2
∗
1
0
5
1<=n<=2*10^5
1<=n<=2∗105,
1
<
=
d
<
=
1
0
18
1<=d<=10^{18}
1<=d<=1018,
1
<
=
a
i
,
b
i
<
=
1
0
9
1<=a_i,b_i<=10^9
1<=ai,bi<=109)
题解:我们把题目要求转化成数学式子:
a
i
−
b
j
<
=
d
a_i-b_j<=d
ai−bj<=d且
b
j
−
a
i
<
=
d
b_j-a_i<=d
bj−ai<=d,转换一下:
a
i
−
d
<
=
b
j
<
=
a
i
+
d
a_i-d<=b_j<=a_i+d
ai−d<=bj<=ai+d,那要求两数之和最大,我们可以枚举
a
i
a_i
ai,二分
b
b
b序列,找到小于等于
a
i
+
d
a_i+d
ai+d最大的那个数,那是不是用
u
p
p
e
r
_
b
o
u
n
d
upper\_bound
upper_bound,然后前一个就可以了。
找完之后判断一下,是不是在
[
1
,
n
]
[1,n]
[1,n]区间,并且满足题目
a
i
−
d
<
=
b
j
<
=
a
i
+
d
a_i-d<=b_j<=a_i+d
ai−d<=bj<=ai+d要求。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 2e5 + 10;
ll n, d, a[N], b[N];
int main() {
ll ans = -1;
cin >> n >> d;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + n);
for (int i = 1; i <= n; i++) {
// a[i] - d <= b[j] <= a[i] + d
ll j = upper_bound(b + 1, b + 1 + n, a[i] + d) - b;
j--;
if (j < 1 || j > n) continue;
if (b[j] >= a[i] - d && b[j] <= a[i] + d) {
ans = max(ans, a[i] + b[j]);
}
}
if (ans == -1) cout << "None";
else cout << ans;
return 0;
}