Make Nonzero Sum (easy version)(hard 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 [a1,a2,…an][a1,a2,…an] consisting of integers −1−1 and 11. You have to build a partition of this array into the set of segments [l1,r1],[l2,r2],…,[lk,rk][l1,r1],[l2,r2],…,[lk,rk] with the following property:

  • Denote the alternating sum of all elements of the ii-th segment as sisi: sisi = ali−ali+1+ali+2−ali+3+…±ariali−ali+1+ali+2−ali+3+…±ari. For example, the alternating sum of elements of segment [2,4][2,4] in array [1,0,−1,1,1][1,0,−1,1,1] equals to 0−(−1)+1=20−(−1)+1=2.
  • The sum of sisi over all segments of partition should be equal to zero.

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

The set of segments [l1,r1],[l2,r2],…,[lk,rk][l1,r1],[l2,r2],…,[lk,rk] is called a partition of the array aa of length nn if 1=l1≤r1,l2≤r2,…,lk≤rk=n1=l1≤r1,l2≤r2,…,lk≤rk=n and ri+1=li+1ri+1=li+1 for all i=1,2,…k−1i=1,2,…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 tt (1≤t≤100001≤t≤10000). Description of the test cases follows.

The first line of each test case contains an integer nn (1≤n≤2000001≤n≤200000) — the length of the array aa.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (aiai is −1−1 or 11) — the elements of the given array.

It's guaranteed that the sum of nn over all test cases does not exceed 200000200000.

Output

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

Then in the ii-th of the following kk lines print two integers lili and riri — description of the ii-th segment. The following conditions should be satisfied:

  • li≤rili≤ri for each ii from 11 to kk.
  • li+1=ri+1li+1=ri+1 for each ii from 11 to (k−1)(k−1).
  • l1=1,rk=nl1=1,rk=n.

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

Example

input

Copy

4

4

1 1 1 1

6

-1 1 1 1 1 1

3

1 -1 1

1

1

output

Copy

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 44. The sum of this segment will be equal to 1−1+1−1=01−1+1−1=0.

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

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

如果是对原数组求和相当于  + a1 + a2 + a3 + a4 + .... + an

每次划分都是将区间内的数 +al  - a(l - 1) + ....

可以观察到如果每个区间内只有一个数,那么和全部求和没有差别!如果区间有两个数,那么第二个数的符号会改变,由此把划分的操作等价为 ------> 选择不连续的几个数(不能选第一个数),使他们符号相反

此题步骤:对原数组求和,设为sum,如果sum是个奇数,那么无解,因为每次改变一个数的正负性会使总体和 +2 或是 -2。

如果sum > 0, 则要找(sum / 2)个不相邻的 1 反转

如果sum < 0,要找(sum / 2)个不相邻的 -1 反转

如果sum == 0 ,那么每个数数为一个区间就好

然后惊奇的发现这份代码c2的也能过

#include<iostream>
#include<vector>

using namespace std;

const int N = 2e5 + 10;

typedef pair<int, int> pii;
int a[N];
int sum;

int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		sum = 0;
		int n;
		cin >> n;
		for(int i = 1; i <= n; i ++)
		{
			scanf("%d", &a[i]); 
			sum += a[i];
		}
		
		vector<pii> ans;
		vector<pii> res;
		
		int l = 1;
		if(sum == 0)
		{
			cout << n << endl;
			for(int i = 1; i <= n; i ++)
			cout << i << " " << i << endl;
		}
		else if(abs(sum) % 2 != 0)
		cout << "-1" << endl;
		else if(sum > 0)
		{
			sum /= 2;
			for(int i = 2; i <= n; i ++)
			{
				if(a[i] > 0)
				{
					ans.push_back({i - 1, i});
					i ++;
					sum --;
					if(sum == 0)
					break;
				}
			}
			if(sum > 0)
			cout << "-1" << endl;
			else
			{
				int last = 0;
				for(int i = 0; i < ans.size(); i ++)
				{
				    if(ans[i].first != last + 1)
				    {
				        for(int j = last + 1; j < ans[i].first; j ++)
				        {
				            res.push_back({j, j});
				        }
				    }
				    last = ans[i].second;
				    res.push_back({ans[i].first, ans[i].second});
				}
				for(int j = last + 1; j <= n; j ++)
				res.push_back({j, j});
				cout << res.size() << endl;
				for(int i = 0; i < res.size(); i ++)
				cout << res[i].first << " " << res[i].second << endl;
			}
		}
		else
		{
			sum /= 2;
			sum = -sum;
			for(int i = 2; i <= n; i ++)
			{
				if(a[i] < 0)
				{
					ans.push_back({i - 1, i});
					i ++;
					sum --;
					if(sum == 0)
					break;
				}
			}
			if(sum > 0)
			cout << "-1" << endl;
			else
			{
				int last = 0;
				for(int i = 0; i < ans.size(); i ++)
				{
				    if(ans[i].first != last + 1)
				    {
				        for(int j = last + 1; j < ans[i].first; j ++)
				        {
				            res.push_back({j, j});
				        }
				    }
				    last = ans[i].second;
				    res.push_back({ans[i].first, ans[i].second});
				}
				for(int j = last + 1; j <= n; j ++)
				res.push_back({j, j});
				cout << res.size() << endl;
				for(int i = 0; i < res.size(); i ++)
				cout << res[i].first << " " << res[i].second << endl;
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值