D2. Remove the Substring (hard version)

25 篇文章 0 订阅

D2. Remove the Substring (hard version)

theme:给定一个串s和它的某个子序列t,现除去s中的一段子串,使得t仍然为s的子序列,问最大能删除多长的子串。|t|<=|s|<=2e5

solution:设t中字符分别为t0t1...tn,则最大值肯定在去除s中最右边满足能形成子序列t的t0之前字符、s中最左边满足能形成子序列t的tn之后的字符、或满足条件的最左边ti与最右边ti+1,的最大值。

所以我们的任务就是预处理出t中每个字符在s中能作为子序列的最左边与最右位置。算最左位置时我们只要按在t中的顺序从左到右找到第一个在s中的位置即可。由于在算ti时已确定了ti-1的位置,所以保证当前的si一定可以构成子序列。求最右最大时从右往左遍历即可。

#include<bits/stdc++.h>
#include<vector>
#include<algorithm>
#define far(i,t,n) for(int i=t;i<n;++i)
#define pb(a) push_back(a)
#define lowbit(x) x&(-x)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int inf=0x3f3f3f3f;
int mod=998244353;
const int maxn=200010;

char s[maxn],t[maxn];
int l[maxn],r[maxn];

int main()
{
    cin>>s>>t;
    int ls=strlen(s),lt=strlen(t);
    for(int i=0,j=0;i<ls&&j<lt;++i)
        if(s[i]==t[j])
            l[j++]=i;
    for(int i=ls-1,j=lt-1;i>=0&&j>=0;--i)
        if(s[i]==t[j])
            r[j--]=i;
    int ans=r[0];
    far(i,1,lt)
        ans=max(ans,r[i]-l[i-1]-1);
    ans=max(ans,ls-l[lt-1]-1);
    cout<<ans<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值