D. Equal Binary Subsequences

D. Equal Binary Subsequences

Everool has a binary string $s$ of length $2n$. Note that a binary string is a string consisting of only characters $0$ and $1$. He wants to partition $s$ into two disjoint equal subsequences. He needs your help to do it.

You are allowed to do the following operation exactly once.

You can choose any subsequence (possibly empty) of s and rotate it right by one position.
In other words, you can select a sequence of indices $b_1,b_2, \dots ,b_m$, where $1 \leq b_1< b_2 < \leq < b_m \leq 2n$. After that you simultaneously set

$$\begin{align*} s_{b_1} &{:=} s_{b_m}, \\ s_{b_2} &{:=} s_{b_1}, \\ &\dots, \\ s_{b_m} &{:=} s_{b_{m-1}} \end{align*}$$

Can you partition $s$ into two disjoint equal subsequences after performing the allowed operation exactly once?

A partition of $s$ into two disjoint equal subsequences $s^p$ and $s^q$ is two increasing arrays of indices $p_1,p_2, \dots ,p_n$ and $q_1,q_2, \dots ,q_n$, such that each integer from $1$ to $2n$ is encountered in either $p$ or $q$ exactly once, $s^p = s_{p1} s_{p2} \dots s_{pn}$, $s^q = s_{q1} s_{q2} \dots s_{qn}$, and $s^p = s^q$.

If it is not possible to partition after performing any kind of operation, report $−1$.

If it is possible to do the operation and partition s into two disjoint subsequences $s^p$ and $s^q$, such that $s^p=s^q$, print elements of $b$ and indices of $s^p$, i. e. the values $p_1,p_2, \dots ,p_n$.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t (1 \leq t \leq {10}^{5})$. Description of the test cases follows.

The first line of each test case contains a single integer $n (1 \leq n \leq {10}^{5})$, where $2n$ is the length of the binary string.

The second line of each test case contains the binary string $s$ of length $2n$.

It is guaranteed that the sum of $n$ over all test cases does not exceed ${10}^{5}$.

Output

For each test case, follow the following output format.

If there is no solution, print $−1$.

Otherwise,

In the first line, print an integer $m (0 \leq m \leq 2n)$, followed by m distinct indices $b_1, b_2, \dots , b_m$(in increasing order).
In the second line, print $n$ distinct indices $p_1, p_2, \dots , p_n$ (in increasing order).

If there are multiple solutions, print any.

Example

input

4
2
1010
3
100010
2
1111
2
1110

output

0
1 2
2 3 5
1 2 5
3 2 3 4
1 4
-1

Note

In the first test case, $b$ is empty. So string $s$ is not changed. Now $s^p = s_1 s_ 2 = 10$, and $s^q = s_3 s_4 = 10$.

In the second test case, $b=[3,5]$. Initially $s_3=0$, and $s_5=1$. On performing the operation, we simultaneously set $s_3=1$, and $s5=0$.

So $s$ is updated to $101000$ on performing the operation.

Now if we take characters at indices $[1,2,5]$ in $s^p$, we get $s_1=100$. Also characters at indices $[3,4,6]$ are in $s^q$. Thus $s^q=100$. We are done as $s^p=s^q$.

In fourth test case, it can be proved that it is not possible to partition the string after performing any operation.

 

解题思路

  首先很容易知道有解的必要条件是$01$串中$1$的个数是偶数,下面证明这个条件也是充分的。

  我们尝试用以下方法来构造答案,每相邻两个字符为一组,因此可以分成$n$组,每组都是$(s_{2i-1},s_{2i}) \, (1 \leq i \leq n)$这个形式。现在假设组内两个元素不同的组有$x$个,那么组内两个元素相同的组有$n-x$个。

  可以证明$x$一定是偶数。

  在组内两个元素相同的$n-x$个组中,假设有$y$组两个元素都是$1$,那么整个$01$串中$1$的个数就是$x + 2 \cdot y$,由于整个$01$串中$1$的个数要为偶数,因此$x + 2 \cdot y$是一个偶数,即$x$是一个偶数。

  现在我们给$x$个两个元素不同的组进行编号$[1 \sim n-x]$,并在每组中按照以下规则选出一个元素:对于编号为奇数的组,我们在这组中选择$1$;对于编号为偶数的组,则选择$0$(当然也可以反过来,奇数组选$0$,偶数组选$1$)。这样我们就会得到一个大小为$\frac{n}{2}$的$0,~1,~0,~1, ~ \dots ,~0,~1$这样$01$交替的序列(所以前面证明$x$是偶数就可以保证这个序列中$0$和$1$的个数是相同的,因此可以实现$01$交替)。同时每组未被选择的元素就会构成$1,~0,~1,~0, ~ \dots ,~1,~0$这样$10$交替的序列。

  这时我们就可以用顺时针偏移操作了,我们对选择出的$0,~1,~0,~1, ~ \dots ,~0,~1$进行一次顺时针偏移,就会得到$1,~0,~1,~0, ~ \dots ,~1,~0$,这就与每组未被选择的元素所构成的序列相同了。

  这时我们再对这两个序列进行组合,那么每组内的元素都是相同的了,即$s_{2i-1}= s_{2i}$。

  上面将$x$个两个元素不同的组通过顺时针偏移变成组内两个元素都相同,再加上本来的$n-x$个两个元素相同的组,此时我们就可以保证每一组内两个元素都相同,这时我们只需要枚举每一组,然后选择每组第一个元素构成序列,就可以构造出两个完全相同的序列的。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 
 6 char s[N];
 7 
 8 void solve() {
 9     int n;
10     scanf("%d %s", &n, s + 1);
11     
12     int cnt = 0;
13     for (int i = 1; i <= n << 1; i++) {
14         cnt += s[i] & 1;
15     }
16     if (cnt & 1) {    // 01串中1的个数是偶数 
17         printf("-1\n");
18         return;
19     }
20     
21     vector<int> ans;    // 用来存放要进行偏移的下标 
22     for (int i = 1, t = 0; i <= n << 1; i += 2) {
23         if (s[i] != s[i + 1]) {    // 这一组内两个元素不相同 
24             // 根据0和1交替选择 
25             if ((s[i] & 1) == t) ans.push_back(i);
26             else ans.push_back(i + 1);
27             t ^= 1;
28         }
29     }
30     
31     printf("%d", ans.size());
32     for (auto &it : ans) {
33         printf(" %d", it);
34     }
35     printf("\n");
36     
37     for (int i = 1; i <= n << 1; i += 2) {
38         printf("%d ", i);    // 此时每组元素内两个元素都相同,选择组内第一个元素 
39     }
40     printf("\n");
41 }
42 
43 int main() {
44     int t;
45     scanf("%d", &t);
46     while (t--) {
47         solve();
48     }
49     
50     return 0;
51 }

 

参考资料

  Codeforces Round #825 (Div. 2) Editorial:https://codeforces.com/blog/entry/107847

  Codeforces Round #825 (Div. 2) A~D:https://zhuanlan.zhihu.com/p/572387762

posted @ 2022-10-11 19:37  onlyblues  阅读(116)  评论(0编辑  收藏  举报
Web Analytics