P8667 [蓝桥杯 2018 省 B] 递增三元组
题目描述
给定三个整数数组 A = [ A 1 , A 2 , ⋯ , A N ] A = [A_1, A_2,\cdots, A_N] A=[A1,A2,⋯,AN], B = [ B 1 , B 2 , ⋯ , B N ] B = [B_1, B_2,\cdots, B_N] B=[B1,B2,⋯,BN], C = [ C 1 , C 2 , ⋯ , C N ] C = [C_1, C_2,\cdots,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,\cdots, A_N$。
第三行包含 N N N 个整数 $ B_1, B_2,\cdots, B_N$。
第四行包含 N N N 个整数 $ C_1, C_2,\cdots, C_N$。
输出格式
一个整数表示答案
输入输出样例 #1
输入 #1
3
1 1 1
2 2 2
3 3 3
输出 #1
27
说明/提示
对于 30 % 30\% 30% 的数据, 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100。
对于 60 % 60\% 60% 的数据, 1 ≤ N ≤ 1000 1 \le N \le 1000 1≤N≤1000。
对于
100
%
100\%
100% 的数据,
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。
二分,纯搜,当然过不了
#include <bits/stdc++.h>
using namespace std;
signed main() {
int n;
cin >> n;
vector<int> a(n), b(n), c(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.begin(), a.end());
sort(b.begin(), b.end());
sort(c.begin(), c.end());
int ans = 0;
vector<int> cntC(n, 0);
int cnt = 0;
for (int i = n - 1; i >= 0; i--) {
cntC[i] = cnt;
cnt += c.end() - upper_bound(c.begin(), c.end(), b[i]);
}
for (int i = 0; i < n; i++) {
auto it = upper_bound(b.begin(), b.end(), a[i]);
if (it != b.end()) {
int idx = it - b.begin();
ans += (b.end() - it) * cntC[idx];
}
}
cout << ans << endl;
return 0;
}
双指针,前缀和优化
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N], b[N], c[N];
int cnta[N], cntc[N], sa[N], sc[N];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
cnta[++a[i]]++;
}
sa[0] = cnta[0];
for (int i = 1; i < N; ++i) sa[i] = sa[i - 1] + cnta[i];
for (int i = 1; i <= n; ++i) cin >> b[i], b[i]++;
for (int i = 1; i <= n; ++i) {
cin >> c[i];
cntc[++c[i]]++;
}
sc[0] = cntc[0];
for (int i = 1; i < N; ++i) sc[i] = sc[i - 1] + cntc[i];
LL ans = 0;
for (int i = 1; i <= n; ++i) {
int b_val = b[i];
ans += (LL)sa[b_val - 1] * (sc[N - 1] - sc[b_val]);
}
cout << ans << endl;
return 0;
}