D. Serval and Shift-Shift-Shift

D. Serval and Shift-Shift-Shift

Serval has two $n$-bit binary integer numbers $a$ and $b$. He wants to share those numbers with Toxel.

Since Toxel likes the number $b$ more, Serval decides to change $a$ into $b$ by some (possibly zero) operations. In an operation, Serval can choose any positive integer $k$ between $1$ and $n$, and change $a$ into one of the following number:

  • $a\oplus(a\ll k)$
  • $a\oplus(a\gg k)$

In other words, the operation moves every bit of $a$ left or right by $k$ positions, where the overflowed bits are removed, and the missing bits are padded with $0$. The bitwise XOR of the shift result and the original $a$ is assigned back to $a$.

Serval does not have much time. He wants to perform no more than $n$ operations to change $a$ into $b$. Please help him to find out an operation sequence, or determine that it is impossible to change $a$ into $b$ in at most $n$ operations. You do not need to minimize the number of operations.

In this problem, $x\oplus y$ denotes the bitwise XOR operation of $x$ and $y$. $a\ll k$ and $a\gg k$ denote the logical left shift and logical right shift.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1\le t\le2\cdot10^{3}$). The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($1\le n\le2\cdot10^{3}$) — the number of bits in numbers $a$ and $b$.

The second and the third line of each test case contain a binary string of length $n$, representing $a$ and $b$, respectively. The strings contain only characters 0 and 1.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2\cdot10^{3}$.

Output

For each test case, if it is impossible to change $a$ into $b$ in at most $n$ operations, print a single integer $-1$.

Otherwise, in the first line, print the number of operations $m$ ($0\le m\le n$).

If $m>0$, in the second line, print $m$ integers $k_{1},k_{2},\dots,k_{m}$ representing the operations. If $1\le k_{i}\le n$, it means logical left shift $a$ by $k_{i}$ positions. If $-n\le k_{i}\le-1$, it means logical right shift $a$ by $-k_{i}$ positions.

If there are multiple solutions, print any of them.

Example

input

3
5
00111
11000
1
1
1
3
001
000

output

2
3 -2
0
-1

Note

In the first test case:

The first operation changes $a$ into $\require{cancel}00111\oplus\cancel{001}11\underline{000}=11111$.

The second operation changes $a$ into $\require{cancel}11111\oplus\underline{00}111\cancel{11}=11000$.

The bits with strikethroughs are overflowed bits that are removed. The bits with underline are padded bits.

In the second test case, $a$ is already equal to $b$, so no operations are needed.

In the third test case, it can be shown that $a$ cannot be changed into $b$.

 

解题思路

  官方给出的题解写得很好,我就按照其思路来写了。

  首先当且仅当$a$与$b$均为全$0$和$a$与$b$均不全为$0$才有解。

  如果$a$为全$0$,那么很明显不管如何操作$a$始终均为全$0$,因此如果$b$不全为$0$那么无解。

  如果$a$不全为$0$,由于每次操作至少左移或者右移一位,因此位移后的结果一定与原串不同,因此异或后的结果一定不为$0$。所以如果$b$为全$0$那么无解。

  然后就是$a$与$b$均不全为$0$的情况了,可以证明一定存在一种方案使得在不超过$n$次的操作下让$a$变成$b$。定义$\text{lb}(a)$为$a$的最低位的$1$的位,$\text{hb}(a)$为$a$的最高位的$1$的位。这里的高低位与二进制的规则相同,即最左边为最高位,最右边为最低位。然后按照下面的$4$个步骤来进行构造:

  1. 如果$\text{hb}(a)<\text{lb}(b)$,那么将$a$左移$\text{lb}(b)-\text{hb}(a)$位,然后异或。经过这步操作后(可能没有)一定有$\text{hb}(a)\geq\text{lb}(b)$。
  2. 考虑$\text{lb}(b)-1,\text{lb}(b)-2,\dots,1$的每一位$i$(注意到此时$b_i$均为$0$),如果$a_i = 1$,那么我们将$a$右移$\text{hb}(a)-i$位然后异或,那么就能将$a_i$置成$0$。完成后就会有$\text{lb}(a)\ge\text{lb}(b)$。
  3. 如果是$\text{lb}(a)>\text{lb}(b)$的情况,我们将$a$右移$\text{lb}(a)-\text{lb}(b)$位然后异或,使得$\text{lb}(a)=\text{lb}(b)$。
  4. 考虑$\text{lb}(b)+1,\text{lb}(b)+2,\dots,n$的每一位$i$,如果$a_i \ne b_i$,那么将$a$左移$i-\text{lb}(a)$位然后异或,那么就能将$a_i$置成$b_i$。完成后就一定会有$a = b$。

  可以发现第$2$步与第$4$步一共最多需要$n-1$次操作。而第$1$步与第$3$步一定不会同时出现,这是因为如果执行了第$1$步那么一定会有$\text{lb}(a)=\text{lb}(b)$而不用执行第$3$步。因此我们最多使用$n$次操作就可以把$a$变成$b$。

  AC代码如下,时间复杂度为$O(n^2)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e3 + 10;
 5 
 6 char sa[N], sb[N];
 7 int a[N], b[N];
 8 
 9 void solve() {
10     int n;
11     scanf("%d %s %s", &n, sa, sb);
12     if (!strcmp(sa, sb)) {    // a和b相等
13         printf("0\n");
14         return;
15     }
16     int ha = n, lb = -1;
17     for (int i = 0; i < n; i++) {
18         a[i] = sa[i] - '0';
19         if (a[i] && ha == n) ha = i;
20     }
21     for (int i = 0; i < n; i++) {
22         b[i] = sb[i] - '0';
23         if (b[i]) lb = i;
24     }
25     if (ha == n || lb == -1) {    // a或b有一个全为0,无解
26         printf("-1\n");
27         return;
28     }
29     vector<int> ans;
30     if (ha > lb) {
31         int d = ha - lb;    // 将a左移ha-lb位
32         for (int i = lb; i + d < n; i++) {
33             a[i] ^= a[i + d];
34         }
35         ha = lb;    // a的最高位变成了lb
36         ans.push_back(d);
37     }
38     for (int i = lb + 1; i < n; i++) {    // 在lb+1...n-1位中把a[i]为1的位变成0
39         if (a[i]) {
40             int d = i - ha;    // 右移i-ha位
41             for (int j = n - 1; j >= i; j--) {
42                 a[j] ^= a[j - d];
43             }
44             ans.push_back(-d);
45         }
46     }
47     int la;    // 求a的最低位的1
48     for (int i = lb; i >= 0; i--) {
49         if (a[i]) {
50             la = i;
51             break;
52         }
53     }
54     if (la < lb) {
55         int d = lb - la;    // 通过把a右移lb-la位使得la=lb
56         for (int i = lb; i - d >= 0; i--) {
57             a[i] ^= a[i - d];
58         }
59         ans.push_back(-d);
60     }
61     for (int i = lb - 1; i >= 0; i--) {    // 在0...lb-1位中把a[i]!=b[i]的位变成b[i]
62         if (a[i] != b[i]) {
63             int d = lb - i;    // 左移lb-i位
64             for (int j = 0; j <= i; j++) {
65                 a[j] ^= a[j + d];
66             }
67             ans.push_back(d);
68         }
69     }
70     printf("%d\n", ans.size());
71     for (auto &x : ans) {
72         printf("%d ", x);
73     }
74     printf("\n");
75 }
76 
77 int main() {
78     int t;
79     scanf("%d", &t);
80     while (t--) {
81         solve();
82     }
83     
84     return 0;
85 }

 

参考资料

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

posted @ 2023-03-01 21:05  onlyblues  阅读(62)  评论(0编辑  收藏  举报
Web Analytics