Codeforces Round #674 (Div. 3) D. Non-zero Segments(前缀和/尺取)垃圾做法

Kolya got an integer array a1,a2,…,an. 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, 00 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≤n≤200000) — the number of elements in Kolya's array.

The second line of the input contains n integers a1,a2,…,an(−109≤ai≤109,ai≠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.

Examples

Input

Copy

4
1 -5 3 2

Output

Copy

1

Input

Copy

5
4 -2 3 -9 2

Output

Copy

0

Input

Copy

9
-1 1 -1 1 -1 1 1 -1 -1

Output

Copy

6

Input

Copy

8
16 -5 -11 -15 10 5 4 -4

Output

Copy

3

首先我们注意到如果某一子段i~j之和为0,那么由前缀和得sum[i - 1] = sum[j]。因此用map记录前缀和,这样就能直接把所有和为0的子段找出来。因为插入的数没有限制,所以可以将问题瞎JB转化为选最少的插入的位置覆盖所有的子段,类似紫书上讲的选最少的点覆盖所有的线段(贪心地尽可能取最右边),不过这个题还要稍微处理一下。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
int n, a[200005];
long long sum[200005] = { 0 };
map<long long, int> mp;
struct Segment
{
	int x, y;
};
bool cmp(Segment a, Segment b)
{
	if(a.y != b.y) return a.y < b.y;
	else return a.x < b.x;
} 
vector<Segment> v;
int main()
{
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d", &a[i]);
		sum[i] = sum[i - 1] + 1ll * a[i];
	}
	mp[0] = 0;
	for(int i = 1; i <= n; i++)
	{
		map<long long, int>::iterator it;
		it = mp.find(sum[i]);
		if(it != mp.end())
		{
			v.push_back(Segment{it->second + 1, i});
			//mp.erase(it);
		}
		//else 
		mp[sum[i]] = i;
	}
	//LRJ 区间选点问题 
    sort(v.begin(), v.end(), cmp);
    if(!v.size())
    {
    	cout << 0;
    	return 0;
	}
    int ans = 1;
    int p = v[0].y - 1;
    for(int i = 1; i < v.size(); i++)
    {
        if(p < v[i].x)
        {
            ans++;
            p = v[i].y - 1;
        }
    }
    if(v.size() == 1) ans = 1;
    cout<<ans;
	return 0;
}
原文地址:https://www.cnblogs.com/lipoicyclic/p/13756711.html