昨晚 学弟来问我这道题,就浅浅理A了一下
题意:
给定
n
=
1
e
6
n=1e6
n=1e6 个公司,
q
=
2
e
6
q=2e6
q=2e6个人,每个公司有
m
i
m_i
mi个岗位,且
∑
i
=
1
n
m
i
=
1
e
6
\sum_{i=1}^{n}{m_i}=1e6
∑i=1nmi=1e6,每个岗位有
A
,
B
,
C
A,B,C
A,B,C 三个属性值,每个人有
a
,
b
,
c
a,b,c
a,b,c 三个属性值。一个人能够胜任这个岗位,当且仅当
A
<
=
a
A<=a
A<=a &&
B
<
=
b
B<=b
B<=b &&
C
<
=
c
C<=c
C<=c (
A
,
a
<
=
400
,
B
,
b
<
=
400
,
C
,
c
<
=
400
A,a<=400,B,b<=400,C,c<=400
A,a<=400,B,b<=400,C,c<=400)。试求,对于每个人,他能在几个公司任职。(学弟给的题意,如果错了,请当这篇博客不存在
思路:
如果没有公司的限制,只是要求 每个人能够在几个岗位任职,就是简单的 三维偏序问题,直接
C
D
Q
CDQ
CDQ 即可,但是有公司的限制,就和种类数类似了,不能考虑
C
D
Q
CDQ
CDQ 了。
但是可以借鉴 C D Q CDQ CDQ 的一些思路,比如,我们可以将所有岗位的 A , B , C A,B,C A,B,C 和 人的 a , b , c a,b,c a,b,c 放在一起,按照 a , A a,A a,A 的大小排序,那么 对于每个人,排在他前面的岗位 就是都满足 A A A 的条件的(也即 像 C D Q CDQ CDQ 一样,通过排序降一维)。
这样处理之后,题目就转化成了,序列上 的 pair 对(B,C),对于每个人
j
j
j,需要求 有多少个公司,满足存在岗位 i,
i
<
j
i
然后,我们看对于每个人
j
j
j,我们需要求有多少个公司,满足存在岗位 i,
i
<
j
i
对于一个人只需要在全局的二维树状数组 查询一个给定点的值即可。
(懒得画图了,有心人可以自己结合上文 画图理解一下)
复杂度分析:
令
M
=
∑
i
=
1
n
m
i
M=\sum_{i=1}^{n}{m_i}
M=∑i=1nmi;
对于每一个岗位都需要在单调序列中二分一下,因为
B
<
=
400
B<=400
B<=400,所以单调序列中最多只有 400个点,所以这部分的复杂度是
M
⋅
l
o
g
2
400
M·log_2{400}
M⋅log2400;
对于每个人,都需要在二维树状数组上查询一次值,这部分复杂度是
q
⋅
l
o
g
2
400
⋅
l
o
g
2
400
q·log_2{400}·log_2{400}
q⋅log2400⋅log2400。
对于每个岗位在 单调序列上最多只会插入一次、删除一次,所以这部分复杂度是
M
⋅
l
o
g
2
400
⋅
l
o
g
2
400
M·log_2{400}·log_2{400}
M⋅log2400⋅log2400
可以发现复杂度是
O
(
能过
)
O(能过)
O(能过) 的,甚至绰绰有余吧。
代码:
因为笔者退役了,代码需要读者自行完成。
当然上面只是口头理A,还有许多细节需要读者自己思考,比如:
因为等式是
<
=
<=
<= 的,所以排序之后需要 按照
B
B
B 值相等的分组, 先把所有的岗位都插入了,再去求答案。
(如果学弟 写出来了,再把代码贴着吧)
#include
#include
using namespace std;
#define ll long long
int main(){
return 0;
}
碎碎:
昨天晚上理A之后给学弟讲完,也算是感概万千,可能如果不退役,自己也能成为一名出色的金牌选手。
这几天,也不知道自己在纠结什么,不知道是后悔还是不甘,也不知道自己喜欢acm是因为 做出题的愉悦,还是因为自己打的还算不错的底子,抑或是这两年在集训队的点滴。
须知少时凌云志 曾许人间第一流