题目描述
给定三个整数数组
A
=
[
A
1
,
A
2
,
…
A
N
]
A = [A_1, A_2, … A_N]
A=[A1,A2,…AN],
B
=
[
B
1
,
B
2
,
…
B
N
]
B = [B_1, B_2, … B_N]
B=[B1,B2,…BN],
C
=
[
C
1
,
C
2
,
…
C
N
]
C = [C_1, C_2, …C_N]
C=[C1,C2,…CN],
请你统计有多少个三元组 ( i , j , k ) (i, j, k) (i,j,k) 满足:
- 1 ≤ i , j , k ≤ N 1 \le i, j, k \le N 1≤i,j,k≤N
- A i < B j < C k A_i < B_j < C_k Ai<Bj<Ck
输入格式
第一行包含一个整数 N N N。
第二行包含 N N N 个整数 A 1 , A 2 , … A N A_1, A_2, … A_N A1,A2,…AN。
第三行包含 N N N 个整数 B 1 , B 2 , … B N B_1, B_2, … B_N B1,B2,…BN。
第四行包含 N N N 个整数 C 1 , C 2 , … C N C_1, C_2, … C_N C1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1
≤
N
≤
1
0
5
1 \le N \le 10^5
1≤N≤105,
0
≤
A
i
,
B
i
,
C
i
≤
1
0
5
0 \le A_i,B_i,C_i \le 10^5
0≤Ai,Bi,Ci≤105
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27
思路
可以使用二分的算法,因为要找的是递增三元组,所以我们可以选定中间的
b
b
b 数组来查找。
先将
a
和
c
a 和 c
a和c 从小到大排序,然后遍历
b
b
b 数组。每当遍历
b
b
b 的一个元素时,使用二分在
a
a
a 中查找第一个小于 当前遍历到的
b
b
b 的元素,记为
p
p
p。同理,二分查找
c
c
c 中第一个大于的记为
q
q
q。然后
(
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;
}