再品二分

98 阅读1分钟

洛谷:www.luogu.com.cn/problem/P86…

给定三个整数数组
A = [A_1, A_2,``````, A_N],
B = [B_1, B_2,``````, B_N],
C = [C_1, C_2,``````, C_N]。

请你统计有多少个三元组 (i, j, k)满足:

1.   1≤i,j,k≤N
2.   A_i < B_j < C_k


输入格式:
第一行包含一个整数 N。
第二行包含 N 个整数 A_1, A_2,``````, A_N
第三行包含 N 个整数 B_1, B_2,``````, B_N
第四行包含 N 个整数 C_1, C_2,``````, C_N

输出格式:
一个整数

eg.
输入:
3
1 1 1
2 2 2
3 3 3

输出:
27

解释:

notes_IMG_20240324_18523677_0_guid(dbbd3439498c4475aacd11cf5a80e14a).jpeg

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();

        int[] A = new int[N];
        int[] B = new int[N];
        int[] C = new int[N];
        for (int i = 0; i < N; i++) {
            A[i]=scan.nextInt();
        }
        for (int i = 0; i < N; i++) {
            B[i]=scan.nextInt();
        }
        for (int i = 0; i < N; i++) {
            C[i]=scan.nextInt();
        }
        Arrays.sort(A);
        Arrays.sort(B);
        Arrays.sort(C);
        int []b = new int[N];
        for (int i = 0; i < N; i++) {
            int left = 0,right = N-1;
            while (left<right){
                int mid = (right+left)/2;
                if(C[mid]>B[i]){
                    right = mid;
                }else {
                    left = mid+1;
                }
            }
            if(C[left]>B[i]){
                b[i]=N-left;
            }
        }
long [] sum = new long [N+1];
        for (int i = 1; i <=N ; i++) {
            sum[i]=sum[i-1]+b[i-1];
        }
        long ans = 0;
        for (int i = 0; i < N; i++) {
            int left = 0,right = N-1;
            while (left<right){
                int mid = (right+left)/2;
                if(B[mid]>A[i]){
                    right = mid;
                }else {
                    left = mid+1;
                }
            }
            if(B[left]>A[i]){
             ans +=sum[N]-sum[left];
            }
        }
        System.out.println(ans);
        }

}