D. Equal Binary Subsequences
D. Equal Binary Subsequences
Everool has a binary string of length . Note that a binary string is a string consisting of only characters and . He wants to partition 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 , where . After that you simultaneously set
Can you partition into two disjoint equal subsequences after performing the allowed operation exactly once?
A partition of into two disjoint equal subsequences and is two increasing arrays of indices and , such that each integer from to is encountered in either or exactly once, , , and .
If it is not possible to partition after performing any kind of operation, report .
If it is possible to do the operation and partition s into two disjoint subsequences and , such that , print elements of and indices of , i. e. the values .
Input
Each test contains multiple test cases. The first line contains the number of test cases . Description of the test cases follows.
The first line of each test case contains a single integer , where is the length of the binary string.
The second line of each test case contains the binary string of length .
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case, follow the following output format.
If there is no solution, print .
Otherwise,
In the first line, print an integer , followed by m distinct indices (in increasing order).
In the second line, print distinct indices (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, is empty. So string is not changed. Now , and .
In the second test case, . Initially , and . On performing the operation, we simultaneously set , and .
So is updated to on performing the operation.
Now if we take characters at indices in , we get . Also characters at indices are in . Thus . We are done as .
In fourth test case, it can be proved that it is not possible to partition the string after performing any operation.
解题思路
首先很容易知道有解的必要条件是串中的个数是偶数,下面证明这个条件也是充分的。
我们尝试用以下方法来构造答案,每相邻两个字符为一组,因此可以分成组,每组都是这个形式。现在假设组内两个元素不同的组有个,那么组内两个元素相同的组有个。
可以证明一定是偶数。
在组内两个元素相同的个组中,假设有组两个元素都是,那么整个串中的个数就是,由于整个串中的个数要为偶数,因此是一个偶数,即是一个偶数。
现在我们给个两个元素不同的组进行编号,并在每组中按照以下规则选出一个元素:对于编号为奇数的组,我们在这组中选择;对于编号为偶数的组,则选择(当然也可以反过来,奇数组选,偶数组选)。这样我们就会得到一个大小为的这样交替的序列(所以前面证明是偶数就可以保证这个序列中和的个数是相同的,因此可以实现交替)。同时每组未被选择的元素就会构成这样交替的序列。
这时我们就可以用顺时针偏移操作了,我们对选择出的进行一次顺时针偏移,就会得到,这就与每组未被选择的元素所构成的序列相同了。
这时我们再对这两个序列进行组合,那么每组内的元素都是相同的了,即。
上面将个两个元素不同的组通过顺时针偏移变成组内两个元素都相同,再加上本来的个两个元素相同的组,此时我们就可以保证每一组内两个元素都相同,这时我们只需要枚举每一组,然后选择每组第一个元素构成序列,就可以构造出两个完全相同的序列的。
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
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16782123.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效