题目链接
Strings in the Pocket
Time Limit: 1 Second Memory Limit: 65536 KB
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|≤2×106), 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×107.
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).
题意:给你两字符串a,b问你把a的一段区间反转能得到b的次数。
当两个字符串相等时,直接用manacher求个数。
如果两个字符串不相等时,找到不相等的前后两个位置,然后往两边更新就好了
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e6+5;
char a[maxn],b[maxn];
int n,Len[maxn],Lentwo[maxn],T;
ll manacher()//manacher算法
{
int l=0,r=0,x;
ll ans=0;
for(int i=1; i<=n; i++)//以奇数个字符为中心找
{
if(i>r)x=1;
else x=min(Len[l+r-i],r-i);
while(i-x>=1&&i+x<=n&&a[i-x]==a[i+x])x++;
Len[i]=x;
ans+=x;
if(i+x-1>r)
{
r=i+x-1;
l=i-x+1;
}
}
l=r=0;
for(int i=1; i<=n; i++)//以偶数个字符为中心找
{
if(i>r)x=0;
else x=min(Lentwo[l+r-i+1],r-i+1);
while(i-x-1>=1&&i+x<=n&&a[i-x-1]==a[i+x])x++;
Lentwo[i]=x;
ans+=x;
if(i+x>=r)
{
l=i-x;
r=i+x-1;
}
}
return ans;
}
int main()
{
cin>>T;
while(T--)
{
scanf("%s",a+1);
scanf("%s",b+1);
n=strlen(a+1);
int x=1,y=n;
for(x; x<=n; x++)
if(a[x]!=b[x])
break;
for(y; y>=1; y--)
if(a[y]!=b[y])
break;
if(x==y)
{
printf("0\n");
}
else if(x<=n)
{
int ans=1;
for(int i=x; i<=y; i++)
{
if(a[i]!=b[x+y-i])
{
ans=0;
break;
}
}
if(ans)
{
x--;
y++;
while(x>=1&&y<=n&&a[x]==b[y]&&a[y]==b[x])
{
ans++;
x--;
y++;
}
}
printf("%d\n",ans);
}
else
{
printf("%lld\n",manacher());
}
}
}