版权声明:蒟蒻写的文章,能看就行了,同时欢迎大佬们指点错误 https://blog.csdn.net/Algor_pro_king_John/article/details/88921053
Problem
给定一个仅包含前 个小写字符的字符串,允许改变其中一个字符,求可能有多少种不同的字符串。
Data constraint
,
Solution
有点坑。。。
具体是分两大类讨论:
即 与 两种情况。
对于前者较为复杂,又分两小类,即 与 两种情况
注意讨论 这样的情况以及交换相邻两个字符的情况
然后就有下面的代码:
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = a; i <= b; i ++)
const int N = 1e5 + 10;
using namespace std;
long long Ans;
int n,m, sum, S[N], Up[N];
bool bz; char s[N];
int main() {
scanf("%d%d", &n, &m);
scanf("%s", s + 1);
F(i, 2, n) S[i] = S[i - 1] + (s[i] != s[i - 1]);
for (int i = 1, j; i <= n; i = j) {
j = i + 2;
while (s[j] == s[i])
j += 2;
for (int k = i; k < j; k += 2)
Up[k] = j - 2;
}
for (int i = 2, j; i <= n; i = j) {
j = i + 2;
while (s[j] == s[i])
j += 2;
for (int k = i; k < j; k += 2)
Up[k] = j - 2;
}
F(i, 1, n - 1)
if (s[i] != s[i + 1]) {
Ans ++; // 特殊情况,即交换S[i]与S[i+1]得到新序列
Ans += m - 2; // 仅仅改变S[i],对应的T[i]只有m-2种情况
Ans += m - 2 + (s[i + 2] == s[i]) + (i + 2 == n + 1); //不能让T[i+1]==S[i]
if (i + 3 <= n + 1 && s[i + 2] == s[i]) Ans --; // 特殊请况
// j==n+1 时没有S[i+1]的限制, 所以是加m
if (i <= n - 2)
Ans ++;
Ans += (m - 1) * (n - i - 1);
Ans += m - 2, bz = 1; // T[i]只有m-2种情况
/*F(j, i + 2, n)
if (s[j] != s[j - 1])
Ans += m - 1;*/
Ans += (S[n] - S[i + 1]) * (m - 1);
// Ans -= max(Up[i], Up[i + 1]) - i - 1;
/*int sum = 0;
F(j, i + 2, n) {
if (bz && s[j] == s[j - 2])
sum ++;
else
bz = 0;
}*/
int w;
if (Up[i] == Up[i + 1] + 1) w = Up[i] - i - 1; else
if (Up[i + 1] == Up[i] + 1) w = Up[i + 1] - i - 1; else
w = min(Up[i], Up[i + 1]) - i;
Ans -= w;
}
else {
Ans += m - 1;
Ans += (S[n] - S[i + 1]) * (m - 1);
}
printf("%lld\n", Ans + m - 1);
}
当然还有很多别的方法。但自己的方法永远是最好的。