递增三元组
题目
给定三个整数数组
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) 满足:
- 1 ≤ i , j , k ≤ N 1≤i,j,k≤N 1≤i,j,k≤N
- A i < B j < C k Ai<Bj<Ck Ai<Bj<Ck
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,…AN 。
第三行包含 N 个整数 B1,B2,…BN。
第四行包含 N 个整数 C1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1 ≤ N ≤ 1 0 5 0 ≤ A i , B i , C i ≤ 1 0 5 1≤N≤10^5 \\ 0≤Ai,Bi,Ci≤10^5 1≤N≤1050≤Ai,Bi,Ci≤105
输入样例
3
1 1 1
2 2 2
3 3 3
输出样例
27
题解
思路
- 前缀和求解
- as[i] 表示在 A[] 中有多少个数小于 b[i]
- cs[i] 表示在 C[] 中有多少个数大于 b[i]
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5 + 20;
long long n, x, a[N], b[N], c[N], cnt[N], s[N], as[N], cs[N];
int main () {
cin >> n;
for (int i = 0; i < n; i ++) { cin >> x; a[i] = ++ x;}
for (int i = 0; i < n; i ++) { cin >> x; b[i] = ++ x;}
for (int i = 0; i < n; i ++) { cin >> x; c[i] = ++ x;}
for (int i = 0; i < n; i ++) cnt[a[i]] ++;
for (int i = 1; i < N; i ++) s[i] = s[i-1] + cnt[i];
for (int i = 0; i < n; i ++) as[i] = s[b[i]-1];
memset(cnt, 0, sizeof cnt);
memset(s, 0, sizeof s);
for (int i = 0; i < n; i ++) cnt[c[i]] ++;
for (int i = 1; i < N; i ++) s[i] = s[i-1] + cnt[i];
for (int i = 0; i < n; i ++) cs[i] = s[N-1] - s[b[i]];
long long res = 0;
for (int i = 0; i < n; i ++) res += (long long)as[i] * cs[i];
cout << res;
return 0;
}