time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The only difference between easy and hard versions is the length of the string.
You are given a string ss and a string tt, both consisting only of lowercase Latin letters. It is guaranteed that tt can be obtained from ss by removing some (possibly, zero) number of characters (not necessary contiguous) from ss without changing order of remaining characters (in other words, it is guaranteed that tt is a subsequence of ss).
For example, the strings "test", "tst", "tt", "et" and "" are subsequences of the string "test". But the strings "tset", "se", "contest" are not subsequences of the string "test".
You want to remove some substring (contiguous subsequence) from ss of maximum possible length such that after removing this substring tt will remain a subsequence of ss.
If you want to remove the substring s[l;r]s[l;r] then the string ss will be transformed to s1s2…sl−1sr+1sr+2…s|s|−1s|s|s1s2…sl−1sr+1sr+2…s|s|−1s|s| (where |s||s| is the length of ss).
Your task is to find the maximum possible length of the substring you can remove so that tt is still a subsequence of ss.
Input
The first line of the input contains one string ss consisting of at least 11 and at most 2⋅1052⋅105 lowercase Latin letters.
The first line of the input contains one string tt consisting of at least 11 and at most 2⋅1052⋅105 lowercase Latin letters.
It is guaranteed that tt is a subsequence of ss.
Output
Print one integer — the maximum possible length of the substring you can remove so that tt is still a subsequence of ss.
Examples
input
Copy
bbaba
bb
output
Copy
3
input
Copy
baaba
ab
output
Copy
2
input
Copy
abcde
abcde
output
Copy
0
input
Copy
asdfasdf
fasd
output
Copy
3以下来自javascript:void(0)
题目大意:给出一段长串s1和它的一段非连续子串s2,求s1最长的连续删除区间,使得s2仍为s1的非连续子串
分析:最大分割情况只可能是两种,一种是最左端或者最右端删去一大段,另一种是中间任意两个字母间删去一大段
先看第一种,那么肯定是要找到s2在s1中的最左相同点和最右相同点,很简单
另一种,删去的区间端点两个字母肯定是s2中相邻的字母,即保证删去中间一段没用的,仍是子串 例如s1:abbccbbbcccddde s2: ab
那么最长区间肯定是找到s1最左端满足条件的a,再找到s1最右端满足条件的b,中间都是可以删的,如果s2:abd 就找到s1最左端满足条件的b,再找到s1最右端满足条件的d,作差值,然后取max
挺有趣的一道题。列为有趣的cf题,当时是真写不出来,看题解居然这么简单,一直想到序列自动机去了,还真是想多了
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define bug(x) cout<<#x<<" is "<<x<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=2e5+10;
char s[N],t[N];
int vis[N],vs[N];
int main()
{
cin>>s+1>>t+1;
int j=1;
int n=strlen(s+1);
int m=strlen(t+1);
for(int i=1;i<=n&&j<=m;++i)
{
if(s[i]==t[j])
{
vis[j]=i;++j;
}
}
j=m;
for(int i=n;i>=1&&j>=1;--i)
{
if(s[i]==t[j])
{
vs[j]=i;
--j;
}
}
int ans=max(vis[1]-1,n-vis[m]);
ans=max(ans,vs[1]-1);
ans=max(ans,n-vs[m]);
for(int i=1;i<=m;++i)
{
ans=max(ans,vs[i]-vis[i-1]-1);
}
printf("%d\n",ans);
}