标签:printf 自动机 class register line lang get gis etc
给定字符串S和T,保证T是S的子序列,求解T在S中对应位置相邻的两个之间距离的最大值。
考虑直接贪心,对于位置i和 i+1,让1到i的子串从前向后匹配,i+1到m的子串从后向前匹配,这样就能让左端点尽量靠左,右端点尽量靠右,距离就是最大的。具体实现可以计算出每个匹配的位置,可以不用子序列自动机,直接贪心找就可以。
#include<bits/stdc++.h>
#define LL long long
#define I inline int
#define V inline void
#define FOR(i,a,b) for(register int i=a,end##i=b;i<=end##i;++i)
#define REP(i,a,b) for(register int i=a,end##i=b;i>=end##i;--i)
#define go(i,a) for(register int i=hed[a];i;i=e[i].pre)
using namespace std;
inline int read()
{
char x=‘\0‘;
int fh=1,sum=0;
for(x=getchar();x<‘0‘||x>‘9‘;x=getchar())if(x==‘-‘)fh=-1;
for(;x>=‘0‘&&x<=‘9‘;x=getchar())sum=sum*10+x-‘0‘;
return fh*sum;
}
const int N=2e5+9;
char ss[N],tt[N];
int n,m,s[N],t[N],a[N],b[N];
int nxt[N][29],las[N][29];
int main()
{
n=read(),m=read();
scanf("%s",ss+1),scanf("%s",tt+1);
FOR(i,1,n)s[i]=ss[i]-‘a‘+1;
FOR(i,1,m)t[i]=tt[i]-‘a‘+1;
s[n+1]=0;
REP(i,n,0)
{
FOR(j,1,26)nxt[i][j]=nxt[i+1][j];
nxt[i][s[i+1]]=i+1;
}
int now=0;
FOR(i,1,m)
{
now=nxt[now][t[i]];
a[i]=now;
}
s[0]=0;
FOR(i,1,n+1)
{
FOR(j,1,26)las[i][j]=las[i-1][j];
las[i][s[i-1]]=i-1;
}
now=n+1;
REP(i,m,1)
{
now=las[now][t[i]];
b[i]=now;
}
int ans=0;
FOR(i,1,m-1)ans=max(ans,b[i+1]-a[i]);
printf("%d",ans);
return 0;
}
标签:printf 自动机 class register line lang get gis etc
原文地址:https://www.cnblogs.com/dinlon/p/14499046.html