0%

Codeforces Round 1085 (Div. 1 + Div. 2)——CF-2207-B. One Night At Freddy's(一定要关注数据范围限制)

题目大意

题目描述

一共有 mm 个玩偶,初始危险值 d1,d2,,dmd_1, d_2, \dots, d_m 均为 0。

整个过程持续 \ell 秒。在每一秒内,会有一个(且仅有一个)玩偶的危险值增加 1。你可以时刻观察到所有玩偶当前的危险值。

你有 nn 次使用手电筒的机会,分别在固定的时间点 a1,a2,,ana_1, a_2, \dots, a_n1a1<a2<<an1 \le a_1 < a_2 < \dots < a_n \le \ell)秒后发生。
每次使用手电筒时,你可以选择恰好一个玩偶,将其危险值重置为 0。每次的选择是互相独立的。

最终的“总危险值”定义为 \ell 秒结束时,所有玩偶危险值的最大值,即 max1jmdj\max_{1 \le j \le m} d_j
你需要求出一个最小的整数 xx,使得无论每一秒是哪个玩偶的危险值增加,你都能通过合理地使用手电筒,保证最终的总危险值不超过 xx

输入格式

第一行包含一个整数 tt1t1041 \le t \le 10^4),表示测试用例的数量。

每个测试用例的第一行包含三个整数 n,m,n, m, \ell1n,m,21051 \le n, m, \ell \le 2 \cdot 10^5nn \le \ell1m21051 \le m \cdot \ell \le 2 \cdot 10^5),分别代表手电筒使用次数、玩偶数量以及总时长。

第二行包含 nn 个整数 a1,a2,,ana_1, a_2, \dots, a_n1a1<a2<<an1 \le a_1 < a_2 < \dots < a_n \le \ell),代表可以使用手电筒的时间点。

保证所有测试用例中 mm \cdot \ell 的总和不超过 21052 \cdot 10^5

输出格式

对于每个测试用例,输出一个整数,即保证最终总危险值不超过的最小值 xx

样例数据

输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
7
1 2 10
10
5 1 32
1 4 9 16 25
2 3 40
13 37
2 2 7
6 7
8 5 60
3 17 20 28 36 44 45 50
6 7 1987
6 7 66 77 666 777
1 1 1
1

输出

1
2
3
4
5
6
7
5
7
19
1
19
1477
0

样例解释

在第一个测试用例中,有 22 个玩偶,总时长为 1010 秒,在第 1010 秒后可使用一次手电筒。可以证明 x=5x=5 总是可行的:1010 秒后,必定有一个玩偶的危险值至少为 55,另一个至多为 55。我们对着危险值较大的那个使用手电筒将其清零,那么最终的最大危险值至多为 55。可以证明 55xx 的最小可能值。

在第二个测试用例中,只有 11 个玩偶,总时长为 3232 秒。由于只有 11 个玩偶,它的危险值每秒必定增加 11。在最后一次使用手电筒(第 2525 秒)时,我们将它的危险值清零。在这之后距离结束还有 77 秒,因此最终危险值必定为 77

在第三个测试用例中,可以证明最小可能的值 xx1919

思路讲解

就是这个 B,哎,感觉基本上是想到了,但是没关注到一个关键的这个数据范围限制

一定要关注数据范围限制

image

你看到这个,基本就知道简单的贪心和这个二分答案是解决不了的。

其实这道题目,这个思路还是不难的,就是,我们想让我们的每一次操作都在最终的答案中贡献最大,是不是?

然后我们发现,如果说后面还有 N 个手电筒,我们如果给 N 个球加,我们其实对这个最终答案的贡献是 0。

image

那怎么办?我们可以给 N+1 个球加。

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ll cnt=N;
while (SZ(st)>cnt+1) {
pop();
}
for (int i=1;i<=L;++i) {
add();
if (incident[i]) {
to_zero();
--cnt;
}
while (SZ(st)>cnt+1) {
pop();
}
}
ll ans=*st.rbegin();

AC代码

AC

https://codeforces.com/contest/2207/submission/365942294

心路历程(WA,TLE,MLE……)