from 神/se
题面
有 n n n 个箱子排成一行,第 i i i 个箱子里最多能装 a i a_i ai 个球。
还有 m m m 个人,第 i i i 个人手里有 c i c_i ci 个球,并且可以往编号在 [ l i , r i ] [l_i,r_i] [li,ri] 中的箱子放球。
每个人还有一个类型 t i ∈ { 0 , 1 } t_i\in\{0,1\} ti∈{0,1}。
对 x = 1 , ⋯ , n x=1,\cdots,n x=1,⋯,n 求出:若将所有 t i = 1 t_i=1 ti=1 的人的限制范围改成 l i ′ = min ( x , l i ) l'_i=\min(x,l_i) li′=min(x,li), r i ′ = max ( r i , x ) r_i'=\max(r_i,x) ri′=max(ri,x),那么最多能放多少个球。
n , m ≤ 2 × 1 0 5 n,m\leq 2\times 10^5 n,m≤2×105, a i , c i ≤ 1 0 9 a_i,c_i\leq 10^9 ai,ci≤109。
题解
若 t i t_i ti 全等于 0 0 0,相当于左边每个点能匹配右边一个区间的二分图匹配问题,贪心即可做到 O ( n log n ) O(n\log n) O(nlogn):从小到大枚举右边的所有点 x x x,过程中将 l ≤ x l\leq x l≤x 的所有区间加入一个堆中,堆顶是 r r r 最小的,那么每次 x x x 肯定优先匹配堆顶。
但对于这题,我们考虑利用 Hall 定理求解,答案可表示为:
∑
i
=
1
m
c
i
−
max
S
⊆
{
1
,
⋯
,
n
}
(
c
(
S
)
−
N
(
S
)
)
\sum_{i=1}^{m}c_i-\max_{S\subseteq\{1,\cdots,n\}}(c(S)-N(S))
i=1∑mci−S⊆{1,⋯,n}max(c(S)−N(S))
N
(
S
)
N(S)
N(S) 表示
S
S
S 能放的箱子的
a
i
a_i
ai 之和。
注意到 N ( S ) N(S) N(S) 一定是若干段两两不交的区间构成,加上一个新的不交的区间 [ L , R ] [L,R] [L,R] 会使权值加上所有 [ l i , r i ] [l_i,r_i] [li,ri] 在 [ L , R ] [L,R] [L,R] 内部的 c i c_i ci 再减去 ∑ j = L R a j \sum_{j=L}^Ra_j ∑j=LRaj。
设 p r e i pre_i prei 表示只考虑那些 t j = 0 t_j=0 tj=0 的人,且 N ( S ) N(S) N(S) 在 [ 1 , i ] [1,i] [1,i] 范围内的 max S ⊆ { 1 , ⋯ , n } ( c ( S ) − N ( S ) ) \max\limits_{S\subseteq\{1,\cdots,n\}}(c(S)-N(S)) S⊆{1,⋯,n}max(c(S)−N(S))。同理设 s u f i suf_i sufi。
使用线段树对每个 j j j 维护 p r e j − 1 + C [ j , i ] − N ( j , i ) pre_{j-1}+C[j,i]-N(j,i) prej−1+C[j,i]−N(j,i) 即可 O ( n log n ) O(n\log n) O(nlogn) 计算 p r e pre pre 和 s u f suf suf,其中 C [ L , R ] C[L,R] C[L,R] 表示所有 [ l i , r i ] [l_i,r_i] [li,ri] 在 [ L , R ] [L,R] [L,R] 内部的 c i c_i ci 之和。
现在考虑对于某
x
x
x 计算答案。考虑
S
S
S 中
t
i
=
1
t_i=1
ti=1 的那些区间,它们肯定都在
N
(
S
)
N(S)
N(S) 中同一个包含
x
x
x 的区间内,那么答案为:
∑
i
=
1
m
c
i
−
max
L
≤
x
≤
R
(
C
[
L
,
R
]
−
∑
i
=
L
R
a
i
+
p
r
e
L
−
1
+
s
u
f
R
+
1
)
\sum_{i=1}^mc_i-\max_{L\leq x\leq R}\bigg(C[L,R]-\sum_{i=L}^Ra_i+pre_{L-1}+suf_{R+1}\bigg)
i=1∑mci−L≤x≤Rmax(C[L,R]−i=L∑Rai+preL−1+sufR+1)
考虑分治。计算跨过
m
i
d
mid
mid 的区间
[
L
,
R
]
[L,R]
[L,R] 对
x
x
x 的贡献,其中
L
lim
≤
L
L_{\lim}\leq L
Llim≤L 且
R
≤
R
lim
R\leq R_{\lim}
R≤Rlim。
具体地,计算 f L f_L fL 表示 max R ∈ [ m i d + 1 , R lim ] ( C [ L , R ] − ∑ i = L R a i + p r e L − 1 + s u f R + 1 ) \max\limits_{R\in[mid+1,R_{\lim}]}\bigg(C[L,R]-\sum_{i=L}^Ra_i+pre_{L-1}+suf_{R+1}\bigg) R∈[mid+1,Rlim]max(C[L,R]−∑i=LRai+preL−1+sufR+1),然后对每个 x ∈ [ L lim , m i d ] x\in[L_{\lim},mid] x∈[Llim,mid] 用 max L ∈ [ L lim , x ] f L \max\limits_{L\in[L_{\lim},x]}f_L L∈[Llim,x]maxfL 更新。对于 x ∈ [ m i d + 1 , R lim ] x\in [mid+1,R_{\lim}] x∈[mid+1,Rlim] 的更新同理。
记 g R = ( C [ L , R ] − ∑ i = L R a i + p r e L − 1 + s u f R + 1 ) g_R=\left(C[L,R]-\sum_{i=L}^Ra_i+pre_{L-1}+suf_{R+1}\right) gR=(C[L,R]−∑i=LRai+preL−1+sufR+1)。那么随着 L L L 变小,我们要做的是对 g R g_R gR 后缀加以及问 g R g_R gR 全局 max \max max。
注意到总共只会有 O ( n ) O(n) O(n) 次 g R g_R gR 的后缀加(每个区间 [ l i , r i ] [l_i,r_i] [li,ri] 只会在跨过 m i d mid mid 时贡献一次),那么直接用线段树维护即可。总时间复杂度 O ( n log n ) O(n\log n) O(nlogn)。