C. Insert Zero and Invert Prefix

codeforces 876c

You have a sequence a1,a2,…,an of length nn, each element of which is either 0 or 1, and a sequence b, which is initially empty.

You are going to perform nn operations. On each of them you will increase the length of bb by 11.

  • On the ii-th operation you choose an integer pp between 00 and i−1i−1. You insert 00 in the sequence bb on position p+1p+1 (after the first pp elements), and then you invert the first pp elements of bb.
  • More formally: let's denote the sequence bb before the ii-th (1≤i≤n1≤i≤n) operation as b1,b2,…,bi−1b1,b2,…,bi−1. On the ii-th operation you choose an integer pp between 00 and i−1i−1 and replace bb with b1¯¯¯¯,b2¯¯¯¯,…,bp¯¯¯¯,0,bp+1,bp+2,…,bi−1b1¯,b2¯,…,bp¯,0,bp+1,bp+2,…,bi−1. Here, x¯¯¯x¯ denotes the binary inversion. Hence, 0¯¯¯=10¯=1 and 1¯¯¯=01¯=0.

You can find examples of operations in the Notes section.

Determine if there exists a sequence of operations that makes bb equal to aa. If such sequence of operations exists, find it.

Input

Each test contains multiple test cases. The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases.

The first line of each test case contains one integer nn (1≤n≤1051≤n≤105) — the length of the sequence aa.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤10≤ai≤1) — the sequence aa.

It is guaranteed that the sum of nn over all test cases does not exceed 105105.

Output

For each test case:

  • output "NO", if it is impossible to make bb equal to aa using the given operations;
  • otherwise, output "YES" in the first line and nn integers p1,p2,…,pnp1,p2,…,pn (0≤pi≤i−10≤pi≤i−1) in the second line — the description of sequence of operations that makes bb equal to aa. Here, pipi should be the integer you choose on the ii-th operation. If there are multiple solutions, you can output any of them.

Example

input

4

5

1 1 0 0 0

1

1

3

0 1 1

6

1 0 0 1 1 0

output

YES
0 0 2 1 3
NO
NO
YES
0 1 0 2 4 2

思路:首先,我们在做的时候应该从后向前做,因为先放前面再放后面前面的会被影响,考虑起来比较复杂。

对于连续的一段0,我们只需要不断的在最前面放0就可以,然后遇到一段1,假设有三个1,我们需要放三个0,然后在这三个0后面放一个0,这样会有三个1,所以要想把x个数变成1,需要x + 1个0,那我们放0的时候要预留一个0帮助他前面的0变成1

具体步骤:首先判断最后一位是否0为,如果为1那么永远不可能,因为不存在一个0使他变为1

然后先找一段0,假设连续x个0,那么可以先放x - 1个0在0位置上,有一个0预留不放,然后找连续的1的个数,假设有y个,那么先放y个0在0的位置上,再放一个0在y位置上,重复此步骤即可

#include<iostream>

using namespace std;

const int N = 1e5 + 10;

int a[N];

int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n;
		cin >> n;
		for(int i = 1; i <= n; i ++)
		cin >> a[i];
		
		if(a[n] == 1)
		cout << "NO";
		else
		{
		    cout << "YES" << endl;
			int cnt0 = 0, cnt1 = 0;
			for(int i = n; i >= 0; i --)
			{
				if(a[i] == 0 && !cnt0 && !cnt1)
					cnt0 ++;
				else if(a[i] == 0 && !cnt1)
				{
					cout << "0 ";
				}
				else if(a[i] == 0 && cnt1)
				{
					cout << cnt1 << " ";
					cnt0 = 1;
					cnt1 = 0;
				}
				else
				{
				    cout << "0 ";
					cnt1 ++;
				}
			}
		}
		
		cout << endl;
	}
 } 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值