题目描述
给定三个整数数组
A=[A1,A2,…AN]A = [A_1, A_2, … A_N]A=[A1,A2,…AN],
B=[B1,B2,…BN]B = [B_1, B_2, … B_N]B=[B1,B2,…BN],
C=[C1,C2,…CN]C = [C_1, C_2, …C_N]C=[C1,C2,…CN],
请你统计有多少个三元组 (i,j,k)(i, j, k)(i,j,k) 满足:
- 1≤i,j,k≤N1 \le i, j, k \le N1≤i,j,k≤N
- Ai<Bj<CkA_i < B_j < C_kAi<Bj<Ck
输入格式
第一行包含一个整数 NNN。
第二行包含 NNN 个整数 A1,A2,…ANA_1, A_2, … A_NA1,A2,…AN。
第三行包含 NNN 个整数 B1,B2,…BNB_1, B_2, … B_NB1,B2,…BN。
第四行包含 NNN 个整数 C1,C2,…CNC_1, C_2, … C_NC1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1≤N≤1051 \le N \le 10^51≤N≤105,
0≤Ai,Bi,Ci≤1050 \le A_i,B_i,C_i \le 10^50≤Ai,Bi,Ci≤105
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27
思路
可以使用二分的算法,因为要找的是递增三元组,所以我们可以选定中间的 bbb 数组来查找。
先将 a和ca 和 ca和c 从小到大排序,然后遍历 bbb 数组。每当遍历 bbb 的一个元素时,使用二分在 aaa 中查找第一个小于 当前遍历到的 bbb 的元素,记为ppp。同理,二分查找 ccc 中第一个大于的记为 qqq。然后 (p+1)×(n−q)(p + 1) \times (n - q)(p+1)×(n−q) 即为当前元素所能找到的递增三元组的数目。
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int a[N], b[N], c[N];
int main()
{
cin >> n;
for ( int i = 0; i < n; i ++ ) cin >> a[i];
for ( int i = 0; i < n; i ++ ) cin >> b[i];
for ( int i = 0; i < n; i ++ ) cin >> c[i];
sort(a, a + n), sort(c, c + n);
long long res = 0;
for ( int i = 0; i < n; i ++ )
{
int l = 0, r = n - 1;
while ( l < r )
{
int mid = (l + r) >> 1;
if ( c[mid] > b[i] ) r = mid;
else l = mid + 1;
}
int p = l;
l = 0, r = n - 1;
while ( l < r )
{
int mid = (l + r + 1) >> 1;
if ( a[mid] < b[i] ) l = mid;
else r = mid - 1;
}
int q = l;
if ( c[p] <= b[i] || b[i] <= a[q] ) continue;
res += (long long)(n - p) * (q + 1);
}
cout << res << endl;
return 0;
}
2328

被折叠的 条评论
为什么被折叠?



