零 (zero)
- 内存限制:512MB
- 时间限制:500ms
- 文件输入输出
- 输入文件:zero.in
- 输出文件:zero.out
题目
题目背景
14 喜欢玩序列
题目描述
14
14
14 有一个长度为
n
n
n 的序列
a
a
a,他规定一个序列的 特征序列
s
s
s 的生成方式为:
对于
∀
1
≤
i
≤
n
,
s
i
=
∑
j
=
1
i
a
j
\forall 1 \leq i \leq n,s_i = \sum_{j = 1}^{i} a_j
∀1≤i≤n,si=∑j=1iaj
14
14
14 规定:如果一个序列
q
q
q 是 美丽序列,当且仅当序列
q
q
q 的 特征序列 中每个元素都不为
0
0
0
14
14
14 想知道能不能将一个序列
a
a
a 重排为一个序列
b
b
b,使得序列
b
b
b 是一个 美丽序列
- 如果可以,请告诉他 YES
- 否则告诉他 NO
由于 14 14 14 有很多个序列想要问你,所以对于每个序列都要告诉他答案
格式
输入格式 (zero.in)
输入第一行,一个整数
T
T
T,表示
14
14
14 手中序列的个数
对于每一个序列:
- 第一行,一个整数 n n n,表示序列的长度
- 第二行, n n n 个整数,表示序列 a a a
输出格式 (zero.out)
输出共 T T T 行,对于第 i i i 行,输出一个字符串 (YES 或 NO) 表示你的答案
样例
样例输入
2
2
1 2
5
-1 1 1 -1 0
样例输出
YES
NO
提示
数据范围
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1≤n≤106, ∑ n ≤ 3 × 1 0 6 , 0 ≤ a i ≤ 1 0 9 \sum n \leq 3 \times 10^6,0 \leq a_i \leq 10^9 ∑n≤3×106,0≤ai≤109
思路
对于序列
p
p
p,记它的特征序列为
q
q
q
q
i
=
p
1
+
p
2
+
p
3
+
⋅
⋅
⋅
⋅
⋅
⋅
+
p
i
q_i = p_1 + p_2 + p_3 + ······ + p_i
qi=p1+p2+p3+⋅⋅⋅⋅⋅⋅+pi
就是
p
p
p 序列前
i
i
i 项的前缀和
我们可以把序列
a
a
a 中
0
0
0 的数全部放在序列的后面,因为
0
0
0 是不影响我们的前缀和
后面的
0
0
0 可以不用考虑,只考虑前面不为
0
0
0 的数
分析
(以下序列都是忽略了
0
0
0 的)
设
b
b
b 的 特征序列 为
c
c
c
c
c
c 的 第
i
i
i 项 是
b
b
b 前
i
i
i 项 的前缀和
所以我们要尽力保证
c
i
c_i
ci 不为
0
0
0
我们可以 逆推:
如果最后一位
c
n
c_n
cn 为
0
0
0,则
c
c
c 不是 美丽序列
如果
c
n
c_n
cn 不是
0
0
0,那么
c
n
−
1
c_{n - 1}
cn−1 一定能保证不为
0
0
0,以此类推(至于为什么,就留给读者自己思考了)
所以我们只需要累加序列 a a a 的每一个数 a i a_i ai,判断它是否为 0 0 0 即可
代码
#include <cstdio>
void Read(long long &n)
{
n = 0LL;
bool f = 1;
char C = getchar();
while (C < '0' || C > '9')
{
if (C == '-') f ^= 1;
C = getchar();
}
while ('0' <= C && C <= '9')
{
n = (n << 3LL) + (n << 1LL) + (C ^ 48);
C = getchar();
}
if (!f) n = -n;
}
int main()
{
freopen("zero.in", "r", stdin);
freopen("zero.out", "w", stdout);
long long T, N, A;
Read(T);
while (T--)
{
Read(N);
long long cnt = 0LL;
for (long long i = 1LL; i <= N; i++)
{ Read(A); cnt += A; }
if (!cnt) printf("NO\n");
else printf("YES\n");
}
return 0;
}