CF1736D
#
,即满足 中可以划分成若干段连续序列,这些序列左半部分和右半部分相等。
【无解】#
显然当 的个数不是偶数时无解。
其他情况有解。
【证明】#
证明中的函数名请见下面【证明中的函数意义】。
我们可以构造一组解:
把所有 , 的 加入集合 。
当 , 时。必然为 或者 。
则下标 可以构造为 。
那么我们知道只有 时成以上 。
此题当有解时一定时 。
证明:
当 , 时, 都是 的倍数,不需考虑。
当 , 时。必然为 或者 。
当 时,则 , 必然出现奇数次,即 都是奇数次。
与 【无解】 情况矛盾。
最后 即为 。
时间复杂度为 。
【证明中的函数意义】#
表示 与 是 的位置。
表示 与 是 的位置。
表示集合 的大小。
#
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <cmath>
#include <sstream>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#define x first
#define y second
#define IOS ios::sync_with_stdio(false)
#define cit cin.tie(0)
#define cot cout.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 100010, M = 100010, MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LLINF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-8;
void solve()
{
int n;
string str;
cin >> n >> str;
int sum = 0;
for (auto x: str) sum += x == '0';
if (sum & 1) cout << -1 << endl;
else
{
vector<int> res;
for (int i = 0; i < n * 2; i += 2)
if (str[i] != str[i + 1])
{
if (str[i] - '0' == res.size() % 2) res.push_back(i + 1);
else res.push_back(i + 2);
}
cout << res.size() << ' ';
for (auto x: res) cout << x << ' ';
cout << endl;
for (int i = 1; i <= n * 2; i += 2) cout << i << ' ';
cout << endl;
}
}
int main()
{
IOS;
cit, cot;
int T = 1;
cin >> T;
while (T -- ) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】