尤利娅有 n n n 个杯子排成一行。其中第 i i i 个杯子装了 a i a_i ai 单位的果汁。尤利娅只用奇数杯喝水,而她的约会对象只用偶数杯喝水。
为了给她的约会对象留下好印象,尤利娅想找到一个连续的子数列,使得如果只考虑这个子数列中的杯子,尤利娅和她的约会对象喝到的果汁总量相同。请帮助她完成这个任务。
更正式地说,如果 l l l 和 r r r 具有相同的奇偶性,那么是否存在两个索引 l , r l , r l,r ,使得 1 ≤ l ≤ r ≤ n , a l + a l + 2 + a l + 4 + ⋯ + a r = a l + 1 + a l + 3 + ⋯ + a r − 1 1≤l≤r≤n , a_l+a_{l+2}+a_{l+4}+⋯+a_r=a_{l+1}+a_{l+3}+⋯+a_{r−1} 1≤l≤r≤n,al+al+2+al+4+⋯+ar=al+1+al+3+⋯+ar−1 和 a l + a l + 2 + a l + 4 + ⋯ + a r − 1 = a l + 1 + a l + 3 + ⋯ + a r a_l+a_{l+2}+a_{l+4}+⋯+a_{r−1}=a_{l+1}+a_{l+3}+⋯+a_r al+al+2+al+4+⋯+ar−1=al+1+al+3+⋯+ar 具有相同的奇偶性。
输入
第一行包含一个整数
t
(
1
≤
t
≤
104
)
t ( 1≤t≤104 )
t(1≤t≤104) - 测试用例数。
每个测试用例的第一行包含一个整数 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n ( 1≤n≤2⋅10^5 ) n(1≤n≤2⋅105) - 眼镜总数。
每个测试用例的第二行包含 n n n 个整数 a 1 , … , a n ( 1 ≤ a i ≤ 1 0 9 ) a1,…,an ( 1≤a_i≤10^9 ) a1,…,an(1≤ai≤109) --每个杯子中的果汁量。
所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2⋅10^5 2⋅105 。
输出
对于每个测试用例,如果存在满足条件的子数组,则输出 “YES”,否则输出 “NO”。
您可以在任何情况下输出答案(例如,字符串 “yEs”、“yes”、"Yes "和 "YES "将被识别为肯定答案)。
首先根据题目的要求,我们需要找到一部分子序列使得
a
l
+
a
l
+
2
+
a
l
+
4
+
⋯
+
a
r
=
a
l
+
1
+
a
l
+
3
+
⋯
+
a
r
−
1
a_l+a_{l+2}+a_{l+4}+⋯+a_r = a_{l+1}+a_{l+3}+⋯+a_{r−1}
al+al+2+al+4+⋯+ar=al+1+al+3+⋯+ar−1 ,所以我们需要满足
a
l
+
a
l
+
2
+
a
l
+
4
+
⋯
+
a
r
−
[
a
l
+
1
+
a
l
+
3
+
⋯
+
a
r
−
1
]
=
0
a_l+a_{l+2}+a_{l+4}+⋯+a_r - [a_{l+1}+a_{l+3}+⋯+a_{r−1}] = 0
al+al+2+al+4+⋯+ar−[al+1+al+3+⋯+ar−1]=0 ,
即
a
l
−
a
l
+
1
+
a
l
+
2
−
a
l
+
3
+
a
l
+
4
+
⋯
−
−
a
r
−
1
+
a
r
=
0
a_l - a_{l+1} +a_{l+2} - a_{l+3} +a_{l+4}+⋯-- a_{r-1} + a_r = 0
al−al+1+al+2−al+3+al+4+⋯−−ar−1+ar=0,所以就可以想到通过前缀和来找到这样一段子序列,使得相加的和为0。
如果想要在输入的时候创造出前缀和然后进行枚举的话必定会超时,这时候就可以通过在枚举过程中维护一个前缀和就可以了,每次标记上出现的前缀和,如果在之后的遍历中搜到了相同的元素,就说明这两段前缀和相减得到的中间子段是满足题目要求的。
CODE:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
#define int long long
void solve(){
int n;cin >> n;
vector<int>a(n+1);
for(int i = 1;i <= n;i++)cin >> a[i];
map<int,bool>vis;
int sum = 0;
vis[0] = 1;
for(int i = 1;i <= n;i++){
if(i % 2)sum += a[i];
else sum -= a[i];
if(vis[sum]){
cout << "YES\n";
return;
}
vis[sum] = 1;
}
cout << "NO\n";
}
signed main(){
int T;cin >> T;
while(T--){
solve();
}
return 0;
}