Problem Description
BaoBao has just found two strings s=s1s2...sn and t=t1t2...tn in his left pocket, where si indicates the i-th character in string s, and ti indicates the i-th character in string t.
As BaoBao is bored, he decides to select a substring of s and reverse it. Formally speaking, he can select two integers l and r such that 1<=l<=r<=n and change the string to s1s2...sl-1srsr-1...sl+1slsr+1...sn-1sn.
In how many ways can BaoBao change s to t using the above operation exactly once? Let (a,b) be an operation which reverses the substring sasa+1...sb, and (c,d) be an operation which reverses the substring scsc+1...sd. These two operations are considered different, if a≠c or b≠d.
Input
There are multiple test cases. The first line of the input contains an integer T, indicating the number of test cases. For each test case:
The first line contains a string s (1<=|s|<=x*10^6), while the second line contains another string t (|t|=|s|). Both strings are composed of lower-cased English letters.
It's guaranteed that the sum of |s| of all test cases will not exceed 2*10^7.
Output
For each test case output one line containing one integer, indicating the answer.
Sample Input
2
abcbcdcbd
abcdcbcbd
abc
abcSample Output
3
3Hint
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).
题意:t 组数据,每组给出两个字符串 s、t,现在要对 t 串进行操作,可以选择任意区间的字符进行翻转直到两字符串相同,问翻转的方法数
思路:
如果串 s 与串 t 相同,则答案为回文子串个数
如果串 s 与串 t 不同,则从头开始寻找第一个不同的位置 l,从尾开始寻找第一个不同的位置 r,如果 l~r 进行翻转后仍不同,则答案为 0,如果翻转后相同,若 s[l-1]=s[r+1],则答案数+1,l--,r++ 继续枚举
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 2000000+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;
char s[N],t[N];
int Len[N<<1],pos;
char temp[N<<1];
int l,r;
LL res;
int init(char *st) {
int len=strlen(st);
temp[0]='$';
for(int i=1; i<=2*len; i+=2) {
temp[i]='#';
temp[i+1]=st[i/2];
}
temp[2*len+1]='#';
temp[2*len+2]='$';
temp[2*len+3]=0;
return 2*len+1;
}
void manacher(char *st,int len) {
int maxx=0,pos=0;
for(int i=1; i<=len; i++) {
if(maxx>i)
Len[i]=min(maxx-i,Len[2*pos-i]);
else
Len[i]=1;
while(st[i-Len[i]]==st[i+Len[i]])
Len[i]++;
if(Len[i]+i>maxx) {
maxx=Len[i]+i;
pos=i;
}
l=(i-1)/2-(Len[i]-1)/2;
r=(i-1)/2+(Len[i]-1)/2;
if(Len[i]&1)
r--;
res+=((r-l+2)/2);
}
printf("%lld\n",res);
return ;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%s%s",s,t);
int n=strlen(s);
res=0;
l=-1;
for(int i=0; i<n; i++) {
if(s[i]!=t[i]) {
l=i;
break;
}
}
if(l!=-1) {
r=-1;
for(int i=n-1; i>=0; i--) {
if(s[i]!=t[i]) {
r=i;
break;
}
}
int j=r;
bool flag=false;
for(int i=l; i<=r; i++,j--) {
if(s[i]!=t[j]) {
flag=1;
break;
}
}
if(flag) {
printf("0\n");
}
else {
res=1;
for(int i=1; i<=l&&r+i<n; i++) {
if(s[l-i]==s[r+i])
res++;
else
break;
}
printf("%lld\n",res);
}
}
else {
int len=init(s);
manacher(temp,len);
}
}
return 0;
}