The score of an array $v_1,v_2,\ldots,v_n$ is defined as the number of indices $i$ ($1 \le i \le n$) such that $v_1+v_2+\ldots+v_i = 0$.

You are given an array $a_1,a_2,\ldots,a_n$ of length $n$. You can perform the following operation multiple times:

select an index $i$ ($1 \le i \le n$) such that $a_i=0$;

then replace $a_i$ by an arbitrary integer.

What is the maximum possible score of $a$ that can be obtained by performing a sequence of such operations?


-----Input-----

Each test contains multiple test cases. The first line contains a single integer $t$ ($1 \le t \le 10^4$) — the number of test cases.

The first line of each test case contains one integer $n$ ($1 \le n \le 2 \cdot 10^5$) — the length of the array $a$.

The second line of each test case contains $n$ integers $a_1,a_2,\ldots,a_n$ ($-10^9 \le a_i \le 10^9$) — array $a$.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot 10^5$.


-----Output-----

For each test case, print the maximum possible score of the array $a$ after performing a sequence of operations.


-----Examples-----

Input
5
5
2 0 1 -1 0
3
1000000000 1000000000 0
4
0 0 0 0
8
3 0 2 -10 10 -30 30 0
9
1 0 0 1 -1 0 1 0 -1
Output
3
1
4
4
5


-----Note-----

In the first test case, it is optimal to change the value of $a_2$ to $-2$ in one operation.

The resulting array $a$ will be $[2,-2,1,-1,0]$, with a score of $3$:

$a_1+a_2=2-2=0$;

$a_1+a_2+a_3+a_4=2-2+1-1=0$;

$a_1+a_2+a_3+a_4+a_5=2-2+1-1+0=0$.

In the second test case, it is optimal to change the value of $a_3$ to $-2000000000$, giving us an array with a score of $1$.

In the third test case, it is not necessary to perform any operations.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Implementation

Greedy algorithms

Complete search

Dynamic programming

Data structures


Solutions:
import collections
import heapq
import sys
import math
import bisect
import os
from io import BytesIO, IOBase
input = sys.stdin.readline

def solve():
	n = int(input())
	l = list(map(int, input().split()))
	dp = [0] * n
	dp[0] = l[0]
	d = collections.defaultdict(int)
	tot = 0
	for i in range(1, n):
		dp[i] = dp[i - 1] + l[i]
	for j in reversed(range(n)):
		d[dp[j]] += 1
		if l[j] == 0:
			tot += max(d.values())
			d.clear()
	tot += d[0]
	print(tot)
for i in range(int(input())):
	solve()


import collections
import sys
sys.setrecursionlimit(25000)
cin = sys.stdin
read = cin.readline
cout = sys.stdout
write = cout.write
ir = lambda : int(read())
rir = lambda : range(int(read()))
mir = lambda : map(int, read().split())
lmir = lambda : list(map(int, read().split()))
iin = lambda : int(input())
riin = lambda : range(int(input()))
miin = lambda : map(int, input().split())
lmiin = lambda : list(map(int, input().split()))
for _ in rir():
	n = ir()
	a = lmir()
	sumpref = 0
	res = 0
	zero_seen = 0
	count = collections.defaultdict(int)
	for i in range(n):
		sumpref += a[i]
		if zero_seen == 0:
			if a[i] == 0:
				zero_seen = 1
				count[sumpref] += 1
			elif sumpref == 0:
				res += 1
		else:
			if a[i] == 0:
				if count:
					res += max(count.values())
				count = collections.defaultdict(int)
			sumpref += a[i]
			count[sumpref] += 1
	if a[n - 1] != 0:
		if count:
			res += max(count.values())
	else:
		res += 1
	print(res)


import sys
from itertools import accumulate
input = sys.stdin.readline
from collections import defaultdict

def solve():
	n = int(input())
	a = list(map(int, input().split()))
	preSum = list(accumulate(a))
	ans = 0
	d = defaultdict(int)
	maxn = 0
	for i in range(n - 1, -1, -1):
		d[preSum[i]] += 1
		maxn = max(maxn, d[preSum[i]])
		if a[i] == 0:
			ans += maxn
			d = defaultdict(int)
			maxn = 0
	ans += d[0]
	return print(ans)
for _ in range(int(input())):
	solve()


import sys
import math
from bisect import bisect_right as br
from collections import deque
from itertools import combinations as cb

def int_arr():
	return list(map(int, sys.stdin.readline().strip().split()))

def str_arr():
	return list(map(str, sys.stdin.readline().strip().split()))

def input():
	return sys.stdin.readline().strip()
for _ in range(int(input())):
	n = int(input())
	arr = int_arr()
	prev = 0
	pref = []
	for i in range(n):
		pref.append(prev + arr[i])
		prev += arr[i]
	d = {}
	ans = 0
	for i in range(n - 1, -1, -1):
		d[pref[i]] = d.get(pref[i], 0) + 1
		if arr[i] == 0:
			ans += max(d.values())
			d.clear()
	ans += d.get(0, 0)
	print(ans)


from itertools import groupby

def Most_Common(lst):
	lst.sort()
	m = 0
	for (k, g) in groupby(lst):
		tmp = len(list(g))
		if tmp > m:
			m = tmp
	return m
t = int(input())
for _ in range(t):
	n = int(input())
	a = list(map(int, input().split()))
	pr_sum = []
	zero_ind = []
	S = 0
	for i in range(n):
		x = a[i]
		S += x
		pr_sum.append(S)
		if x == 0:
			zero_ind.append(i)
	zero_ind.append(n)
	answer = 0
	answer += pr_sum[:zero_ind[0]].count(0)
	N = len(zero_ind)
	for k in range(N - 1):
		i = zero_ind[k + 1]
		j = zero_ind[k]
		answer += Most_Common(pr_sum[j:i])
	print(answer)


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	ls = [int(x) for x in input().split()]
	dp = [0] * (n + 1)
	for i in range(1, n + 1):
		dp[i] = dp[i - 1] + ls[i - 1]
	s = 0
	d = {}
	for i in reversed(range(n)):
		d[dp[i + 1]] = d.get(dp[i + 1], 0) + 1
		if ls[i] == 0:
			s += max(d.values())
			d.clear()
	s += d.get(0, 0)
	print(s)


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	a = list(map(int, input().split()))
	pref = [0] * (n + 1)
	for i in range(1, n + 1):
		pref[i] = pref[i - 1] + a[i - 1]
	ans = 0
	d = {}
	for j in reversed(range(n)):
		d[pref[j + 1]] = d.get(pref[j + 1], 0) + 1
		if a[j] == 0:
			ans += max(d.values())
			d.clear()
	ans += d.get(0, 0)
	print(ans)


t = int(input())
while t > 0:
	a = int(input())
	b = list(map(int, input().split()))
	ans = 0
	sum = 0
	d = {}
	maxCount = 0
	for i in range(len(b) - 1, -1, -1):
		if b[i] == 0:
			zeroCount = 0
			if 0 in d:
				zeroCount = d[0]
			ans += max(maxCount, 1 + zeroCount)
			sum = 0
			d = {}
			maxCount = 0
		else:
			sum += b[i]
			if sum in d:
				d[sum] += 1
			else:
				d[sum] = 1
			if d[sum] > maxCount:
				maxCount = d[sum]
	if len(d) != 0:
		ans += d[sum] - 1
		if sum == 0:
			ans += 1
	print(ans)
	t -= 1


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	a = list(map(int, input().split()))
	chk = 0
	d = {}
	s = 0
	ans = 0
	for i in range(n):
		s = s + a[i]
		if a[i] == 0:
			if chk == 1:
				c = 0
				for x in d:
					c = max(c, d[x])
				d = {}
				ans += c
				d[str(s)] = 1
			else:
				chk = 1
				if str(0) in d:
					ans += d[str(0)]
				d = {}
				d[str(s)] = 1
		elif str(s) in d:
			d[str(s)] += 1
		else:
			d[str(s)] = 1
	c = 0
	if chk == 1:
		for x in d:
			if c < d[x]:
				c = d[x]
	elif str(0) in d:
		c = d[str(0)]
	ans += c
	print(ans)


for _ in range(int(input())):
	n = int(input())
	A = list(map(int, input().split()))
	Z = []
	if not A[0]:
		Z.append(0)
	C = [A[0]]
	for i in range(1, n):
		C.append(C[-1] + A[i])
		if not A[i]:
			Z.append(i)
	z = len(Z)
	Z.append(n)
	total = C[:Z[0]].count(0)
	sum_zeros = 0
	for i in range(z):
		if i < z - 1:
			next_zi = Z[i + 1]
		else:
			next_zi = n
		if next_zi - Z[i] == 1:
			total += 1
			continue
		counter = {val: 0 for val in set(C[Z[i]:next_zi])}
		max_app = 0
		for j in range(Z[i], next_zi):
			counter[C[j]] += 1
			max_app = max(max_app, counter[C[j]])
		total += max_app
	print(total)


def max_beauty(arr):
	cumsum = [0 for i in range(len(arr) + 1)]
	not_first = False
	first_beauty = 0
	for i in range(len(arr)):
		if arr[i] == 0:
			not_first = True
		cumsum[i + 1] = cumsum[i] + arr[i]
		if cumsum[i + 1] == 0 and (not not_first):
			first_beauty += 1
	beauty = 0
	cnt = dict()
	for i in range(len(arr) - 1, -1, -1):
		if cumsum[i + 1] in cnt:
			cnt[cumsum[i + 1]] += 1
		else:
			cnt[cumsum[i + 1]] = 1
		if arr[i] == 0 and cnt:
			max_v = 0
			for (k, v) in cnt.items():
				if v > max_v:
					max_v = v
					max_k = k
			if max_v:
				beauty += max_v
				cnt.clear()
	if cnt:
		beauty += first_beauty
	return beauty
for i in range(int(input())):
	n = input()
	arr = [int(i) for i in input().split()]
	print(max_beauty(arr))


for _ in range(int(input())):
	n = int(input())
	a = list(map(int, input().split()))
	dp = [0] * (n + 1)
	for i in range(1, n + 1):
		dp[i] = dp[i - 1] + a[i - 1]
	s = 0
	d = {}
	for i in range(n - 1, -1, -1):
		d[dp[i + 1]] = d.get(dp[i + 1], 0) + 1
		if a[i] == 0:
			s += max(d.values())
			d.clear()
	s += d.get(0, 0)
	print(s)


t = int(input())
for _ in range(t):
	n = int(input())
	a = [int(i) for i in input().strip().split()]
	s = []
	curr = 0
	for i in range(n):
		curr += a[i]
		s.append(curr)
	ans = 0
	l = []
	for i in range(n):
		if a[i] == 0:
			l.append(i)
		a[i] = ans
		if s[i] == 0:
			ans += 1
	already = 0
	d = {}
	maxf = 0
	if l:
		j = len(l) - 1
		for i in range(n - 1, -1, -1):
			d[s[i]] = d.get(s[i], 0) + 1
			maxf = max(maxf, d[s[i]])
			if i == l[j]:
				j -= 1
				d = {}
				already += maxf
				maxf = 0
		print(max(ans, a[l[0]] + already))
	else:
		print(ans)


t = int(input())
for _ in range(t):
	n = int(input())
	arr = list(map(int, input().split()))
	first_zero = False
	s = 0
	poss = []
	res = 0
	for i in range(len(arr)):
		if arr[i] == 0:
			if first_zero == True:
				count = {}
				for e in poss:
					count[e] = count.get(e, 0) + 1
				best_val = max(count, key=lambda x: count[x])
				res += count[best_val]
				s += best_val
				poss = []
			elif first_zero == False:
				first_zero = True
		s += arr[i]
		if first_zero == False and s == 0:
			res += 1
		if first_zero:
			poss.append(-s)
	if len(poss) > 0:
		count = {}
		for e in poss:
			count[e] = count.get(e, 0) + 1
		best_val = max(count, key=lambda x: count[x])
		res += count[best_val]
		s += best_val
	print(res)


from collections import Counter

def solve(lst):
	prefix = [0] * len(lst)
	total = 0
	for (i, x) in enumerate(lst):
		total += x
		prefix[i] = total

	def find(st, ed):
		elements = prefix[st:ed]
		elements.sort()
		elements.append(None)
		largest = 0
		largest_e = None
		curr = 0
		curr_e = None
		for (i, ele) in enumerate(elements):
			if curr_e == ele:
				curr += 1
			else:
				if curr > largest:
					largest = curr
					largest_e = curr_e
				curr_e = ele
				curr = 1
		return (largest_e, largest)
	zeros = [i for (i, x) in enumerate(lst) if x == 0]
	added = 0
	res = 0
	if zeros:
		for i in range(zeros[0]):
			if prefix[i] == 0:
				res += 1
	else:
		for i in range(len(prefix)):
			if prefix[i] == 0:
				res += 1
	zeros.append(len(lst))
	for i in range(len(zeros) - 1):
		nextZero = zeros[i + 1]
		(val, maxCount) = find(zeros[i], nextZero)
		prefval = prefix[i]
		added += val - (prefval + added)
		res += maxCount
	return res
for _ in range(int(input())):
	input()
	lst = list(map(int, input().split()))
	print(solve(lst))


import math
for i in range(int(input())):
	input()
	b = [int(x) for x in input().split()]
	prefix = []
	su = 0
	zero_Count = 0
	ans = 0
	for i in range(len(b)):
		su += b[i]
		if b[i] == 0:
			zero_Count += 1
		if zero_Count == 0 and su == 0:
			ans += 1
			continue
		if zero_Count == 0:
			continue
		prefix.append([su, zero_Count])
	prefix = sorted(prefix, key=lambda x: x[0])
	v = {}
	count = 1
	for j in range(len(prefix)):
		if j != 0 and prefix[j] == prefix[j - 1]:
			count += 1
		else:
			count = 1
		if prefix[j][1] not in v:
			v[prefix[j][1]] = count
		else:
			v[prefix[j][1]] = max(count, v[prefix[j][1]])
	for k in v.keys():
		ans += v[k]
	print(ans)


import sys
input = sys.stdin.readline
from random import getrandbits

class Wrp(int):
	RANDOM = getrandbits(32)

	def __init__(self, x):
		int.__init__(x)

	def __hash__(self):
		return super(Wrp, self).__hash__() ^ self.RANDOM
for _ in range(int(input())):
	n = int(input())
	a = list(map(int, input().split()))
	chk = 0
	d = {}
	s = 0
	ans = 0
	for i in range(n):
		s = s + a[i]
		if a[i] == 0:
			if chk == 1:
				c = 0
				for x in d:
					c = max(c, d[x])
				d = {}
				ans += c
				d[Wrp(s)] = 1
			else:
				chk = 1
				if Wrp(0) in d:
					ans += d[Wrp(0)]
				d = {}
				d[Wrp(s)] = 1
		elif Wrp(s) in d:
			d[Wrp(s)] += 1
		else:
			d[Wrp(s)] = 1
	c = 0
	if chk == 1:
		for x in d:
			if c < d[x]:
				c = d[x]
	elif Wrp(0) in d:
		c = d[Wrp(0)]
	ans += c
	print(ans)