C1. Make Nonzero Sum (easy version)

C1. Make Nonzero Sum (easy version)

This is the easy version of the problem. The difference is that in this version the array can not contain zeros. You can make hacks only if both versions of the problem are solved.

You are given an array $[a_1,a_2, \dots a_n]$ consisting of integers $−1$ and $1$. You have to build a partition of this array into the set of segments $[l_1,r_1],[_l2,r_2], \dots ,[l_k,r_k]$ with the following property:

  • Denote the alternating sum of all elements of the $i$-th segment as $s_i$: $s_i = a_{l_i} - a_{l_i+1} + a_{l_i+2} - a_{l_i+3} + \ldots \pm a_{r_i}$. For example, the alternating sum of elements of segment $[2,4]$ in array $[1,0,−1,1,1]$ equals to $0−(−1)+1=2$.
  • The sum of $s_i$ over all segments of partition should be equal to zero.

Note that each $s_i$ does not have to be equal to zero, this property is about sum of $s_i$ over all segments of partition.

The set of segments $[l_1,r_1],[l_2,r_2], \dots ,[l_k,r_k]$ is called a partition of the array a of length $n$ if $1=l_1 \leq r_1,l_2 \leq r_2, \dots ,l_k \leq r_k=n$ and $r_{i+1}=l_{i+1}$ for all $i=1,2, \dots k−1$. In other words, each element of the array must belong to exactly one segment.

You have to build a partition of the given array with properties described above or determine that such partition does not exist.

Note that it is not required to minimize the number of segments in the partition.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ $(1 \leq t \leq 10000)$. Description of the test cases follows.

The first line of each test case contains an integer $n$ $(1 \leq n \leq 200000)$ — the length of the array a.

The second line of each test case contains $n$ integers $a_1,a_2, \dots ,a_n$ ($a_i$ is $−1$ or $1$) — the elements of the given array.

It's guaranteed that the sum of $n$ over all test cases does not exceed $200000$.

Output

For each test case, if required partition does not exist, print $−1$. Otherwise, print an integer $k$ — the number of segments in the partition.

Then in the $i$-th of the following $k$ lines print two integers $l_i$ and $r_i$ — description of the $i$-th segment. The following conditions should be satisfied:

  • $l_i \leq r_i$ for each $i$ from $1$ to $k$.
  • $l_{i+1}=r_{i+1}$ for each $i$ from $1$ to $(k−1)$.
  • $l_1=1,r_k=n$.

If there are multiple correct partitions of the array, print any of them.

Example

input

4
4
1 1 1 1
6
-1 1 1 1 1 1
3
1 -1 1
1
1

output

1
1 4
2
1 3
4 6
-1
-1

Note

In the first test case we can build a partition of one segment of length $4$. The sum of this segment will be equal to $1−1+1−1=0$.

In the second test case we can build a partition of two segments of length $3$. The sum of the first segment will be equal to $−1−1+1=−1$, and the sum of the second segment: $1−1+1=1$. So, the total sum will be equal to $−1+1=0$.

In the third and in the fourth test cases it can be proved that there are no required partition.

 

解题思路

  如果序列的长度为奇数,那么一定无解。将序列的每一个数加起来得到总和$s$,我们对任意一个数取反:

  • 如果是$1$,则取反得到$-1$,此时序列的总和变成$s - 1 + (-1) = s - 2$,$s$的奇偶性不变。
  • 如果是$-1$,则取反得到$1$,此时序列的总和变成$s - (-1) + 1 = s + 2$,$s$的奇偶性不变。

  因此可以发现,对序列中任意的数取反,总和$s$的奇偶性都不会发生改变。由于当序列长度为奇数时,任意的$-1$和$1$相加得到的总和必定时奇数,因此无论怎么改变序列中的数都不会使得总和变偶数,因此总和无法变成$0$,即无解。

  那么当序列长度为偶数时就一定有解了吗?只要我们能构造出一种合理的划分方案就能说明有解。

  由于此时的序列长度为偶数,因此我们可以先对相邻的两个元素分成一组,得到$(1, 2), (3, 4), \dots (n - 1, n)$。考虑第$i$组$(2i-1, 2i)$,如果$a_{2i - 1} = a_{2i}$,那么就将这组作为答案,此时这组的总和为$a_{2i - 1} - a_{2i} = 0$。否则如果$a_{2i - 1} \ne a_{2i}$,那么就分成两组,分别是$[2i - 1, 2i - 1]$和$[2i, 2i]$,第一组的和为$a_{2i - 1}$,第二组的和为$a_{2i}$,因此这两组加起来和就为$a_{2i - 1} + a_{2i} = 0$。

  可以发现按照上面这种规则对序列进行分组后元素总和必定为$0$。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 
 6 int a[N];
 7 
 8 void solve() {
 9     int n;
10     scanf("%d", &n);
11     for (int i = 1; i <= n; i++) {
12         scanf("%d", a + i);
13     }
14     if (n & 1) {
15         printf("-1\n");
16         return;
17     }
18     vector<pair<int, int>> ans;
19     for (int i = 1; i <= n; i += 2) {
20         if (a[i] == a[i + 1]) ans.push_back({i, i + 1});
21         else ans.push_back({i, i}), ans.push_back({i + 1, i + 1});
22     }
23     printf("%d\n", ans.size());
24     for (auto &it : ans) {
25         printf("%d %d\n", it.first, it.second);
26     }
27 }
28 
29 int main() {
30     int t;
31     scanf("%d", &t);
32     while (t--) {
33         solve();
34     }
35     
36     return 0;
37 }

 

参考资料

  Codeforces Round #829 Editorial:https://codeforces.com/blog/entry/108336

posted @ 2022-10-24 23:22  onlyblues  阅读(68)  评论(0编辑  收藏  举报
Web Analytics