C2. Make Nonzero Sum (hard version)
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

This is the hard version of the problem. The difference is that in this version the array contains 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, 00 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 = aliali+1+ali+2ali+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=l1r1,l2r2,,lkrk=n1=l1≤r1,l2≤r2,…,lk≤rk=n and ri+1=li+1ri+1=li+1 for all i=1,2,k1i=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 (1t100001≤t≤10000). Description of the test cases follows.

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

The second line of each test case contains nn integers a1,a2,,ana1,a2,…,an (aiai is 1−1, 00, 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 print an integer kk — the number of segments in the partition. If required partition does not exist, print 1−1.

If partition exists, 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:

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

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

inputCopy
5
4
0 0 0 0
7
-1 1 0 1 0 1 0
5
0 -1 1 0 1
3
1 0 1
1
1
outputCopy
4
1 1
2 2
3 3
4 4
4
1 1
2 2
3 5
6 7
-1
2
1 1
2 3
-1

#include <iostream>
#include <cstring>
using namespace std;
const int N=2e5+10;
int t,n;
int a[N],sum;
bool p[N];
typedef struct{
    int l,r;
}node;
node res[N];
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        sum=0;
        memset(p,0,sizeof p);
        for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
        for(int i=2;i<=n;i++){
            if(sum>0&&a[i]==1){
                p[i-1]=1;
                sum-=2;
                i++;
            }
            else if(sum<0&&a[i]==-1){
                p[i-1]=1;
                sum+=2;
                i++;
            }
        }
        if(sum!=0){
            cout<<-1<<endl;
            continue;
        }
        int l,r,num=0;
        for(int i=1;i<=n;i++){
            l=i;
            r=i;
            if(p[i]){
            while(i<=n&&p[i]) r=i+1,i+=2;
            i--;
        }
            res[num++]={l,r};
        }
        cout<<num<<endl;
        for(int i=0;i<num;i++) cout<<res[i].l<<" "<<res[i].r<<endl;
    }
}

 

原文地址:http://www.cnblogs.com/liyiyang/p/16824190.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性