Strings in the Pocket
BaoBao has just found two strings and in his left pocket, where indicates the -th character in string , and indicates the -th character in string .
As BaoBao is bored, he decides to select a substring of and reverse it. Formally speaking, he can select two integers and such that and change the string to .
In how many ways can BaoBao change to using the above operation exactly once? Let be an operation which reverses the substring , and be an operation which reverses the substring . These two operations are considered different, if or .
Input
There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:
The first line contains a string (), while the second line contains another string (). Both strings are composed of lower-cased English letters.
It's guaranteed that the sum of of all test cases will not exceed .
Output
For each test case output one line containing one integer, indicating the answer.
Sample Input
2 abcbcdcbd abcdcbcbd abc abc
Sample Output
3 3
Hint
For the first sample test case, BaoBao can do one of the following three operations: (2, 8), (3, 7) or (4, 6).
For the second sample test case, BaoBao can do one of the following three operations: (1, 1), (2, 2) or (3, 3).
https://www.cnblogs.com/whdsunny/p/10785922.html
题意:
存在S串和T串 要求对S串的一个子串做一次翻转操作可以得到T串的方案数
思路:
对子串分两种情况
第一种是S串和T串完全相同 可以的方案数就是S串中的所有的回文子串 因为S串长度为2e6 必须要用马拉车线性去处理出所有的回文子串
第二种是S串和T串有不同的部分 找出两个不同的字符最远的位置(l,r) 先判断S串的这个区间是否能通过翻转变成T串的区间 如果不可以直接输出0 如果可以 则向两侧同时延展寻找是否可以翻转
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
const int N = 4e6 + 7;
char s1[N], s2[N], s[N];
int p[N];
int init(int len) {
s[0] = '$', s[1] = '#';
int leng = 1;
for (int i = 1; i <= len; ++i) {
s[++leng] = s1[i];
s[++leng] = '#';
}
s[++leng] = '@';
s[++leng] = '\0';
return leng-2;
}
void manacher(int len) {
int id = 0, mx = 0;
for (int i = 1; i <= len; ++i) {
p[i] = i < mx ? min(p[2*id-i], mx-i) : 1;
while (s[i + p[i]] == s[i - p[i]]) ++p[i];
if (mx < i + p[i]) mx = i + p[i], id = i;
}
}
int main() {
int t;
scanf ("%d", &t);
while (t--) {
scanf ("%s %s", s1+1, s2+1);
int len = strlen(s1+1), pos1 = -1, pos2 = -1;
for (int i = 1; i <= len; ++i) {
if (s1[i] != s2[i]) {
pos1 = i; break;
}
}
for (int i = len; i >= 1; --i) {
if (s1[i] != s2[i]) {
pos2 = i; break;
}
}
if (pos1 == -1) {
len = init(len);
manacher(len);
long long ans = 0;
for (int i = 1; i <= len; ++i) ans += p[i]/2;
printf ("%lld\n", ans);
} else {
int flag = 1;
for (int i = pos1; i <= pos2; ++i) {
if (s1[i] != s2[pos2 - (i-pos1)]) {
flag = 0; break;
}
}
if (!flag) {
puts("0");
} else {
long long ans = 0;
while (s1[pos1] == s2[pos2] && s1[pos2] == s2[pos1] && pos1 >= 1 && pos2 <= len) {
--pos1, ++pos2, ++ans;
}
printf ("%lld\n", ans);
}
}
}
return 0;
}