import io,os
import bisect
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
class segment_max(object):
def merge(self,num,minimum):
return max(minimum,num)
def __init__(self,n):
self.n = n
self.arr = [-2147483647]*(2*n)
def update(self,index,target):
if self.arr[index] >= target:
return
self.arr[index] = target
if index & 1:
nexttarget = self.merge( self.arr[index], self.arr[index-1])
else:
nexttarget = self.merge( self.arr[index], self.arr[index+1])
if index>0: self.update(index>>1,nexttarget )
def addnum(self,index,diff):
self.update(index+self.n, self.arr[index+self.n] + diff)
def query(self,left,right):
i,j = self.n+left, self.n+right+1
output = -2147483648
while i<j:
if i&1:
output = self.merge(self.arr[i],output)
i += 1
if j&1:
j -= 1
output = self.merge(self.arr[j],output)
i = i >> 1
j = j >> 1
return output
def main(t):
n = int(input())
arr = list(map(int,input().split()))
accu = [0]*(n+1)
for i in range(n):
accu[i] = accu[i-1] + arr[i]
temp = []
for i in range(n):
temp.append((accu[i],i))
temp.append((0,-1))
temp.sort()
cor = {}
index = 0
for [accunum,i] in temp:
if str(accunum) not in cor:
cor[str(accunum)] = index
index += 1
seg_min = segment_max(n+1)
seg_max = segment_max(n+1)
index = cor[str(0)]
seg_min.update(index+n+1,1)
seg_max.update(index+n+1,-1)
maxdp = {}
curr = 0
maxdp[str(curr)] = 0
for i in range(n):
index = cor[str(accu[i])]
num1 = seg_min.query(0,index-1) + i
num2 = seg_max.query(index+1,n) - i
if str(accu[i]) in maxdp:
num3 = maxdp[str(accu[i])]
else: num3 = -2147483648
num = max(num1,num2,num3)
if str(accu[i]) in maxdp:
maxdp[str(accu[i])] = max(maxdp[str(accu[i])],num)
else:
maxdp[str(accu[i])] = num
seg_min.update(index+n+1, num-i )
seg_max.update(index+n+1, num+i )
print(num)
T = int(input())
t = 1
while t<=T:
main(t)
t += 1
#include <bits/stdc++.h>
#define ll long long
#define lld long double
#define ff first
#define ss second
#define pb push_back
#define vr(v) v.begin(),v.end()
#define rv(v) v.rbegin(),v.rend()
#define Code ios_base::sync_with_stdio(false);
#define By cin.tie(NULL);
#define Davit cout.tie(NULL);
using namespace std;
//#include "algo/debug.h"
struct node {
ll pos, neg;
};
vector<node> seg;
int sz = 1;
node merge(node a, node b) {
return {max(a.pos, b.pos), max(a.neg, b.neg)};
}
void modify(int l, int r, int x, int index, node value) {
if (l == r) {
seg[x] = merge(seg[x], value);
return;
}
int m = (l + r) / 2;
if (m >= index) modify(l, m, x + x + 1, index, value);
else modify(m + 1, r, x + x + 2, index, value);
seg[x] = merge(seg[x + x + 1], seg[x + x + 2]);
}
void modify(int index, node value) {
modify(0, sz - 1, 0, index, value);
}
node get(int l, int r, int x, int lx, int rx) {
if (l >= lx && r <= rx)return seg[x];
if (l > rx || r < lx)return {(ll) -1e9, (ll) -1e9};
int m = (l + r) >> 1;
node a = get(l, m, x + x + 1, lx, rx);
node b = get(m + 1, r, x + x + 2, lx, rx);
return merge(a, b);
}
node get(int l, int r) {
return get(0, sz - 1, 0, l, r);
}
void solve() {
int n;
cin >> n;
vector<ll> v(n);
for (int i = 0; i < n; i++)cin >> v[i];
vector<ll> pref(n + 1);
for (int i = 1; i <= n; i++) {
pref[i] = v[i - 1] + pref[i - 1];
}
vector<ll> compress = pref;
sort(vr(compress));
compress.resize(unique(vr(compress)) - compress.begin());
for (int i = 0; i <= n; i++) {
pref[i] = lower_bound(vr(compress), pref[i]) - compress.begin();
}
sz = (int) compress.size();
int SZ = 1;
while (SZ < sz)SZ <<= 1;
sz = SZ;
seg = vector<node>(sz + sz, {(ll) -1e9, (ll) -1e9});
vector<ll> dp(n + 1, -1e9);
vector<ll> zero(sz, -1e9);
dp[0] = 0;
for (int i = 0; i <= n; i++) {
int index = (int) pref[i];
if (i) {
dp[i] = zero[index];
dp[i] = max(dp[i], get(0, index - 1).pos + i);
dp[i] = max(dp[i], get(index + 1, sz - 1).neg - i);
}
zero[pref[i]] = max(zero[index], dp[i]);
modify(index, {dp[i] - i, dp[i] + i});
}
cout << dp[n] << endl;
}
int main() {
int t;
cin >> t;
while (t--)solve();
}
1605B - Reverse Sort | 1607C - Minimum Extraction |
1604B - XOR Specia-LIS-t | 1606B - Update Files |
1598B - Groups | 1602B - Divine Array |
1594B - Special Numbers | 1614A - Divan and a Store |
2085. Count Common Words With One Occurrence | 2089. Find Target Indices After Sorting Array |
2090. K Radius Subarray Averages | 2091. Removing Minimum and Maximum From Array |
6. Zigzag Conversion | 1612B - Special Permutation |
1481. Least Number of Unique Integers after K Removals | 1035. Uncrossed Lines |
328. Odd Even Linked List | 1219. Path with Maximum Gold |
1268. Search Suggestions System | 841. Keys and Rooms |
152. Maximum Product Subarray | 337. House Robber III |
869. Reordered Power of 2 | 1593C - Save More Mice |
1217. Minimum Cost to Move Chips to The Same Position | 347. Top K Frequent Elements |
1503. Last Moment Before All Ants Fall Out of a Plank | 430. Flatten a Multilevel Doubly Linked List |
1290. Convert Binary Number in a Linked List to Integer | 1525. Number of Good Ways to Split a String |