D. Equal Binary Subsequences
题意
给定一个长度为 2 n 2n 2n 的 01 01 01 字符串 s s s,现在需要恰好使用一次下面的操作,将其划分为相等的两个子序列
定义操作:
- 选择某些下标,并这些下标代表的子序列向右循环移动一位
如果可以成功划分,输出操作序列
思路
首先不难发现: 1 1 1 和 0 0 0 的个数必须是偶数,因为两个子序列要相等
我们先给出 结论 ,如果 1 1 1 和 0 0 0 个数是偶数,那么一定可以成功划分
方法如下:
先将 s s s 按照: ∀ i ∈ [ 1 , n ] \forall i \in [1,n] ∀i∈[1,n],分成 n n n 个 ( s 2 i − 1 , s i ) (s_{2i - 1},s_{i}) (s2i−1,si) 这样的配对,假设有 x x x 个 s 2 i − 1 ≠ s 2 i s_{2i-1} \neq s_{2i} s2i−1=s2i,那么剩下 n − x n - x n−x 个都是相等的配对。我们可以得出: x x x 一定是偶数
这是因为: 1 1 1 的数量是偶数,且 1 1 1 在 n − x n-x n−x 个相等配对中出现偶数次,在 x x x 个不等配对中出现 x x x 次,那么为了最终数量为偶数, x x x 必须为偶数才行
对于那些相等的配对,我们可以一个分给 s 1 s_1 s1,另外一个分给 s 2 s_2 s2,对于那些不等的配对,我们可以在奇数次的时候将 0 0 0 分给 s 1 s_1 s1,在偶数次的时候将 1 1 1 分给 s 1 s_1 s1。这样子 s 1 = 0 , 1 , 0 , 1 , 0 , 1 , . . . 0 , 1 s_1 =0,1,0,1,0,1,...0,1 s1=0,1,0,1,0,1,...0,1, s 2 = 1 , 0 , 1 , 0 , 1 , 0 , . . . , 1 , 0 s2 = 1,0,1,0,1,0,...,1,0 s2=1,0,1,0,1,0,...,1,0
它们恰好等于彼此反转,如果我们对于分配给 s 1 s_1 s1 的那些下标,执行一次循环右移操作, s 1 s_1 s1 就会变成: 1 , 0 , 1 , 0 , 1 , 0 , . . . , 1 , 0 1,0,1,0,1,0,...,1,0 1,0,1,0,1,0,...,1,0,相当于将 s 1 s_1 s1 翻转了。此时 s 1 = s 2 s_1 = s_2 s1=s2
#include<bits/stdc++.h>
#define fore(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;const int INF=0x3f3f3f3f;
const long long INFLL=1e18;typedef long long ll;void solve(){int n;std::cin >> n;std::string s;std::cin >> s;int n1 = 0;for(auto c : s) n1 += (c == '1');if(n1 & 1){std::cout << -1 << endl;return;}s = '0' + s;std::vector<std::pair<int, int>> v;for(int i = 1; i < 2 * n; i += 2)if(s[i] != s[i + 1])v.emplace_back(i, i + 1);std::vector<int> op;fore(i, 0, v.size()){auto [p1, p2] = v[i];if(i & 1){if(s[p1] == '1') op.push_back(p1);else op.push_back(p2);}else{if(s[p1] == '0') op.push_back(p1);else op.push_back(p2);}}std::cout << op.size() << ' ';for(auto i : op) std::cout << i << ' '; //翻转s1std::cout << endl;for(int i = 1; i < 2 * n; i += 2) std::cout << i << ' ';std::cout << endl;
}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int t;std::cin >> t;while(t--){solve();}return 0;
}