这个题的数据量比较大,单纯的暴力是O(n^3^),次数会达到10^15^,这是在搞笑,得亏蓝桥是OI赛制,否则这个题AC个人觉得是比较困难的,但是经过学习提示以后这个题也不难,主要就是
枚举b这个数组,因为如果枚举a,b和c的关系不稳定,需要再一层枚举去控制b和c的关系(枚举c的道理一样),所以首先想到枚举b以后优化a和c,具体优化方法有2个,二分法和前缀和法。
第一个方法二分,需要将三个数组排序,利用二分logN的速度拿到a和c分别的上下限,然后计算得出。
第二个是前缀和,利用cnt[]数组,下标的含义是下标这个值在a和c中出现的次数,然后用s[]统计出cnt的前缀和,相当于某个阈值以内数的总和,很巧妙的方法。
方法一: 二分法
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
public static void main(String[] args) throws IOException {
String ss[] = br.readLine().split(" ");
int n = Integer.parseInt(ss[0]);
int a[] = new int[n];
int b[] = new int[n];
int c[] = new int[n];
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) a[i] = Integer.parseInt(ss[i]);
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) b[i] = Integer.parseInt(ss[i]);
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) c[i] = Integer.parseInt(ss[i]);
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
long res = 0;
int left, right;
for (int i = 0; i < n; i++) {
int l = 0, r = n - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (a[mid] < b[i]) l = mid;
else r = mid - 1;
}
if (a[l] >= b[i]) l = -1;
left = l;
l = 0;
r = n - 1;
while (l < r) {
int mid = l + r >> 1;
if (c[mid] > b[i]) r = mid;
else l = mid + 1;
}
if (b[i] >= c[r]) r = n;
right = r;
res += ((long) (n - right) * (left + 1));
}
pw.print(res);
pw.flush();
pw.close();
br.close();
}
}
方法二:前缀和
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int N = 100010;
static int a[] = new int[N], b[] = new int[N], c[] = new int[N];
static int cnt[] = new int[N], s[] = new int[N];
static int as[] = new int[N], cs[] = new int[N];
public static void main(String[] args) throws IOException {
String ss[] = br.readLine().split(" ");
int n = Integer.parseInt(ss[0]);
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
a[i] = Integer.parseInt(ss[i]);
a[i]++;
}
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
b[i] = Integer.parseInt(ss[i]);
b[i]++;
}
ss = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
c[i] = Integer.parseInt(ss[i]);
c[i]++;
}
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];
Arrays.fill(cnt, 0);
Arrays.fill(s, 0);
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 res = 0;
for (int i = 0; i < n; i++) res += (long) as[i] * cs[i];
pw.print(res);
pw.flush();
pw.close();
br.close();
}
}