Codeforces Round #579 (Div. 3) D2. Remove the Substring (hard version)

本文探讨了一道算法题,旨在找出原串中可删除的最长连续子串,使得另一给定子串仍作为原串的子序列。通过记录子串在原串中的边界,实现了高效求解。

D2. Remove the Substring (hard version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between easy and hard versions is the length of the string.

You are given a string s and a string t, both consisting only of lowercase Latin letters. It is guaranteed that t can be obtained from s by removing some (possibly, zero) number of characters (not necessary contiguous) from s without changing order of remaining characters (in other words, it is guaranteed that t is a subsequence of s).

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 s of maximum possible length such that after removing this substring t will remain a subsequence of s.

If you want to remove the substring s[l;r] then the string s will be transformed to s1s2…sl−1sr+1sr+2…s|s|−1s|s| (where |s| is the length of s).

Your task is to find the maximum possible length of the substring you can remove so that t is still a subsequence of s.

Input
The first line of the input contains one string s consisting of at least 1 and at most 2⋅105 lowercase Latin letters.

The second line of the input contains one string t consisting of at least 1 and at most 2⋅105 lowercase Latin letters.

It is guaranteed that t is a subsequence of s.

Output
Print one integer — the maximum possible length of the substring you can remove so that t is still a subsequence of s.

题目大意:给你一个原串s和其子串t,问在原串中删除一段连续序列,使得t串依旧是s串的子串,求该删除掉的序列的最大长度为多少。

思路:找到t序列中的每个下标对应的在s串中的左界和右界。因为t串是有序的,相邻两个字母中间的才可以删除掉。那么,怎么才能使删除掉的串长度最大呢?对于每个下标对应字母的左界l和右界r中间任何与该字母相同的都可以使用。那么,显而易见,a[i].r-a[i-1].l是最优解。即t串中上个字母的l与下个字母r的距离。只需要将原串正反遍历一遍即可。最后和两端的长度比较一下得出答案。

ACcode:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
string s,t;
struct node
{
    int l;
    int r;
}a[200010];
int main ()
{
    cin>>s>>t;
    if(s==t) printf("0\n");
    else{
    int index = 0;
    int R = t.length()-1;
      for(int i=0;i<s.length();i++)
      {
          if(s[i]==t[index])
          {
              a[index].l = i;
              index++;
          }
      }
      index = t.length()-1;
      for(int i=s.length()-1;i>0;i--)
      {
          if(s[i]==t[index])
          {
              a[index].r = i;
              index--;
          }
      }
      int yi = s.length()-a[R].l-1;
      int er = a[0].r;
      int ans = max(yi,er);
      for(int i=1;i<t.length();i++)
      {
          ans = max(a[i].r-a[i-1].l-1,ans);
      }
      printf("%d\n",ans);
    }
      return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值