首页 > 技术文章 > A 组队参赛

Limbo-To-Heaven 2019-08-17 15:07 原文

时间限制 : - MS   空间限制 : - KB 
评测说明 : 1s,256m
问题描述

一年一度的信息学竞赛NK校赛即将开始,何老板在组织安排报名工作。
南开信竞队分为小学、初中、高中三个梯队:
小学梯队有N个队员,年龄分别是A1,A2,……,AN
初中梯队有N个队员,年龄分别是B1,B2,……,BN
高中梯队有N个队员,年龄分别是C1,C2,……,CN
比赛是组队参赛,三人一队,要求每只队伍里面必须要有小学、初中和高中各一人。同时,要求每个队中,小学队员的年龄<初中队员的年龄<高中队员的年龄。
何老板想知道,总共可能的组队方案有多少种?请你帮他算一算。两种组队方案中,至少存在一个不相同的同学,即被认为是不同方案。

输入格式

第一行,一个整数N
接下来三行,每行N个整数,分别表示每个梯队的队员年龄:


输出格式

一个整数,表示不同的组队方案总数。

样例输入 1

2
1 5
2 4
3 6

样例输出 1

3

样例输入 2

3
1 1 1
2 2 2
3 3 3

样例输出 2

27

样例输入 3

6
3 14 159 2 6 53
58 9 79 323 84 6
2643 383 2 79 50 288

样例输出 3

87

提示

1 ≤ N ≤ 105
1 ≤ Ai ≤ 109(1 ≤ i ≤ N)
1 ≤ Bi ≤ 109(1 ≤ i ≤ N)

1 ≤ Ci ≤ 109(1 ≤ i ≤ N)

【分析】

  首先观察题意,很简单我们可以知道是要我们找到所有递减的三元数组的个数。有很多方法都可以做到,但要小心,一不小心就会O(n2)。我们先对A,B,C三个数组从小到大排序,重点放在B数组上。因为sort的关系,自然可以用lower_bound、upper_bound处理A,C中的可行选择个数,之后用乘法原理即可解答。

【标程】

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define R register int
 4 #define ll long long
 5 #define For(i, s, n) for (R i = s; i <= n; ++ i)
 6 #define maxn 100005
 7 using namespace std;
 8 int n;
 9 ll ans;
10 int A[maxn], B[maxn], C[maxn];
11 inline char nc(){  
12     static char buf[100000],*p1 = buf, *p2 = buf;  
13     return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++;  
14 }  
15 inline int read(){  
16     char ch = nc(); 
17     int sum = 0;  
18     while (!(ch >= '0' && ch <= '9'))ch = nc();  
19     while (ch >= '0' && ch <= '9')sum = sum * 10 + ch - 48, ch = nc();  
20     return sum;  
21 } 
22 void ini() {
23     scanf("%d", &n);
24     For (i, 1, n)A[i] = read();
25     For (i, 1, n)B[i] = read();
26     For (i, 1, n)C[i] = read();
27     sort(A + 1, A + n + 1);
28     sort(B + 1, B + n + 1);
29     sort(C + 1, C + n + 1);
30 }
31 void solve() {
32     For (i, 1, n) {
33         ll p = lower_bound(A + 1, A + n + 1, B[i]) - A - 1;   // lower_bound是查找从左起第一个大于等于的位置下标,p减1是因为题目要求严格小于
34         ll q = upper_bound(C + 1, C + n + 1, B[i]) - C - 1;   // upper_bound是查找从左起第一个大于等于的位置下标
35         ans += p * (n - q);   // 乘法原理
36     }
37     printf("%lld", ans);
38 }
39 int main() {
40     ini();
41     solve();
42     return 0;
43 }

 

 

推荐阅读