1426D - Non-zero Segments

原题链接:

Problem - 1426D - Codeforces

题目描述:

Kolya got an integer array $$$a_1, a_2, \dots, a_n$$$. The array can contain both positive and negative integers, but Kolya doesn't like $$$0$$$, so the array doesn't contain any zeros.

Kolya doesn't like that the sum of some subsegments of his array can be $$$0$$$. The subsegment is some consecutive segment of elements of the array.

You have to help Kolya and change his array in such a way that it doesn't contain any subsegments with the sum $$$0$$$. To reach this goal, you can insert any integers between any pair of adjacent elements of the array (integers can be really any: positive, negative, $$$0$$$, any by absolute value, even such a huge that they can't be represented in most standard programming languages).

Your task is to find the minimum number of integers you have to insert into Kolya's array in such a way that the resulting array doesn't contain any subsegments with the sum $$$0$$$.

Input

The first line of the input contains one integer $$$n$$$ ($$$2 \le n \le 200\,000$$$) — the number of elements in Kolya's array.

The second line of the input contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$-10^{9} \le a_i \le 10^{9}, a_i \neq 0$$$) — the description of Kolya's array.

Output

Print the minimum number of integers you have to insert into Kolya's array in such a way that the resulting array doesn't contain any subsegments with the sum $$$0$$$.

题目大意:

给定一个不含0的整数数组,问最少需要插入几个整数,使得整个数组中没有和为0的连续子段。

解题思路:

计算该数组的前缀和,前缀和为0 ,计数器加1,前缀和出现过两次一样的也加1(用Set存储记录出现过的前缀和)

计数器每次更新后,前缀和更新为当前的数字。并且将当前Set清空。(因为前面的已经确定不会有0和子段了,自然也就无需维护)

代码(CPP):

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
const int INF = 0x3fffffff;

/*
    计算该数组的前缀和,前缀和为0 ,计数器加1,前缀和出现过两次一样的也加1(用Set存储记录出现过的前缀和)
    计数器每次更新后,前缀和更新为当前的数字。并且将当前Set清空。(因为前面的已经确定不会有0和子段了,自然也就无需维护)
*/

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout.precision(18);

    int n, cnt = 0, sum = 0;
    cin >> n;
    set<int> Set;
    for (int i = 1, x; i <= n; i++)
    {
        cin >> x;
        sum += x;
        if (sum == 0 || Set.count(sum))
        {
            cnt++;
            Set.clear();
            sum = x;
        }
        Set.insert(sum);
    }
    cout << cnt << endl;

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值