题目描述:
给定三个整数数组
A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],
请你统计有多少个三元组 (i,j,k) 满足
1≤i,j,k≤N
Ai<Bj<Ck
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,…AN。
第三行包含 N 个整数 B1,B2,…BN。
第四行包含 N 个整数 C1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai,Bi,Ci≤105
要点:
- 三重枚举一定是不能过的
- 那么对A和C数组进行计数和前缀和预处理,枚举B,找到在A中小于B 在C中大于B的数量相乘
- 用到了前缀和,注意数组中可能出现0,而前缀和经常把s[0]默置为0
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
const int MAXN = 1e5+10;
int a[MAXN], b[MAXN], c[MAXN], cnta[MAXN], cntc[MAXN];
LL sa[MAXN], sc[MAXN], ans;
int n;
int main() {
cin >> n;
int maxx = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
cnta[a[i]]++;
maxx = max(maxx, a[i]);
}
for(int i = 1; i <= n; i++) scanf("%d", &b[i]), maxx = max(maxx, b[i]);
for(int i = 1; i <= n; i++) {
scanf("%d", &c[i]);
cntc[c[i]]++;
maxx = max(maxx, c[i]);
}
sa[0] = cnta[0];
sc[0] = cntc[0];
for(int i = 1; i <= maxx; i++) {
sa[i] = sa[i-1] + cnta[i];
sc[i] = sc[i-1] + cntc[i];
}
for(int i = 1; i <= n; i++) {
ans += (int)sa[b[i] - 1] * (n - sc[b[i]]);
}
cout << ans << endl;
return 0;
}