CF_r981_div3----D. Kousuke's Assignment
写在前面:该题转载至codeforces Codeforces Round 981 (Div. 3)😃
题目描述:
Codeforces Round 981 (Div. 3)----D. Kousuke’s Assignment
time limit per test2 seconds
memory limit per test256 megabytes
After a trip with Sakurako, Kousuke was very scared because he forgot about his programming assignment. In this assignment, the teacher gave him an array a of n integers and asked him to calculate the number of non-overlapping segments of the array a, such that each segment is considered beautiful.
A segment [l,r] is considered beautiful if al+al+1+⋯+ar−1+ar=0.
For a fixed array a, your task is to compute the maximum number of non-overlapping beautiful segments.
在和 Sakurako 一起旅行后,Kousuke 非常害怕,因为他忘记了他的编程作业。在这次作业中,老师给了他一个包含 n 个整数的数组 a,并要求他计算数组 a 中不重叠线段的数量,使得每个线段都被认为是美丽的。
如果线段 [l,r] 满足 al+al+1+⋯+ar−1+ar=0 则该线段被认为是美丽的。
对于固定数组 a,您的任务是计算不重叠的美丽线段的最大数量。
输入:
The first line of input contains the number t (1≤t≤104) — the number of test cases. Each test case consists of 2 lines.
-
The first line contains one integer n (1≤n≤105) — the length of the array.
-
The second line contains n integers ai (−105≤ai≤105) — the elements of the array a.
It is guaranteed that the sum of n across all test cases does not exceed 3⋅105.
输入的第一行包含数字 t (1≤t≤104) — 测试用例的数量。每个测试用例由 2 行组成。
第一行包含一个整数 n (1≤n≤105) — 数组的长度。第二行包含 n个整数 a_i (−105≤a_i≤105) — 数组 a的元素。保证所有测试用例的 n 的总和不超过 3⋅105。
输出:
For each test case, output a single integer: the maximum number of non-overlapping beautiful segments.
对于每个测试用例,输出一个整数:不重叠的美丽线段的最大数量。
样例:
输入:
3
5
2 1 -3 2 1
7
12 -4 4 43 -3 -5 8
6
0 -4 0 3 0 1
输出:
1
2
3
题目解析:
那必须是狠狠贪心,这是个前缀和的经典模板题,题目等价于求给定数组的不重叠的和为零的子数组数量,那可以从头遍历过去,如果遍历到的元素a与其之前的连续m个元素的和为0,那这m+1个数对应的就是一个和为零的子数组。
此时记录当前符合条件的子数组数量的变量sum自增,然后把a及其之前的元素无视掉,即不再参与后面的前缀和判断。
例如样例中的第一个给定数组arr[5]={2 1 -3 2 1}
,遍历未开始的时候sum=0,遍历到a_0 = 2,那么第一个数及其之前的元素的和为2。
这里说明一下,这里如果用map记录的话时间复杂度是优于用数组存储直接遍历的,或者每次遍历新元素都将其逐个往前累加,直到和为0
或者遍历到了数组边界。(感觉不用map的话会被hacker用TL打掉)
继续往后遍历,第二个数及其之前的元素之和为3,到第三个元素及其之前元素之和为0,而sum=0的情况在遍历还未开始时出现过,所以sum(arr[0],arr[2])==0
,满足条件,所以把前三个元素抛开,sum++
后值为1。
再继续往后遍历,第四,五个元素分别与其之前的元素 (到上次满足条件的最后1个元素为止,此处为arr[2]后面的元素才参与计算) 求和的结果都未出现重复数字,所以返回最后结果sum=1。
完整代码:
1 |
|