题目链接:AcWing 1236. 递增三元组
给定三个整数数组
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
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27
程序说明:
三重循环会超时,可以只循环b数组,在a和c数组中分别求出比b[i]小的个数和比b[i]大的个数(二分),由于a和c互斥,可以用乘法原理相乘。
注意需要特判,因为有可能a中所有的数都大于等于b[i](或者c中所有的数都小于等于b[i])
代码如下:
import java.util.*;
import java.io.*;
public class Main {
static int N = 100010, n;
static int[] a = new int[N];
static int[] b = new int[N];
static int[] c = new int[N];
static long res;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();
//输入数据
for(int i = 0; i < n; i++)
a[i] = sc.nextInt();
for(int i = 0; i < n; i++)
b[i] = sc.nextInt();
for(int i = 0; i < n; i++)
c[i] = sc.nextInt();
//排序
Arrays.sort(a, 0, n);
Arrays.sort(b, 0, n);
Arrays.sort(c, 0, n);
//查找
for(int i = 0; i < n; i++) {
int x = find1(b[i]);
int y = find2(b[i]);
if(a[x] >= b[i]) //特判
x = -1;
if(c[y] <= b[i])
y = n;
res += (long)(x + 1) * (long)(n - y);
}
System.out.println(res);
}
//在a数组中找最后一个小于b[i]的
public static int find1(int x) {
int l = 0, r = n - 1;
while(l < r) {
int mid = l + r + 1 >> 1;
if(a[mid] < x) l = mid;
else r = mid - 1;
}
return l;
}
//在c数组中找第一个大于b[i]的
public static int find2(int x) {
int l = 0, r = n - 1;
while(l < r) {
int mid = l + r >> 1;
if(c[mid] > x) r = mid;
else l = mid + 1;
}
return l;
}
}