C - Flippy Sequence
基本信息
题解
首先求出在哪些区间内, 和 是不同的。
两次操作最多只能对两个区间进行翻转。如果不同的区间数超过两个则无解,答案为 。
接下来讨论不同区间数量有 ,, 个的情况。
无不同区间
若 和 相等,则两次操作必须翻转同一个区间,才能保持 不变。因此答案就是非空区间的数量,即 。
一个不同区间
若有一个不同的区间,有以下两类选法。设目标区间的长度为 。

第一类:选择两个不相交的区间,它们的并集是目标区间。共有 种方法。
第二类:选择两个相交的区间,它们的差是目标区间。共有 种方法。
因此答案为 。
两个不同区间
若有两个不同的区间,有以下三类选法。

两个区间有先后之分,因此答案为 。
时间复杂度 。
参考代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | #include <bits/stdc++.h>
#define MAXN ((int) 1e6)
using namespace std;
typedef pair<int, int> pii;
int n;
char A[MAXN + 10], B[MAXN + 10];
void solve() {
scanf("%d%s%s", &n, A + 1, B + 1);
// 计算不同区间
vector<pii> vec;
int bgn = -1;
for (int i = 1; i <= n; i++) if (A[i] != B[i]) {
if (A[i - 1] == B[i - 1]) bgn = i;
if (A[i + 1] == B[i + 1]) vec.push_back(pii(bgn, i));
}
// 分类讨论
if (vec.size() == 0) printf("%lld\n", 1LL * n * (n - 1) / 2 + n);
else if (vec.size() == 1) printf("%d\n", 2 * (n - 1));
else if (vec.size() == 2) printf("6\n");
else printf("0\n");
}
int main() {
int tcase; scanf("%d", &tcase);
while (tcase--) solve();
return 0;
}
|