这个题意转化下,其实是 给两个串 A,B,给1e5组询问:求A[l..r]和B的LCS
由于B的len很小,只有20,所以我们考虑预处理A,求出A的序列自动机,然后在B上进行dp
dp[i,j]表示B[1..i]已经匹配了j位的最短的A[l..r]前缀,这样是很好转移的
#include<bits/stdc++.h> using namespace std; #define N 200005 int n,m,nxt[N][26],pos[26]; char s[N],t[N]; int main(){ int T;cin>>T; while(T--){ cin>>(s+1)>>(t+1); n=strlen(s+1); m=strlen(t+1); for(int i=0;i<26;i++)pos[i]=n+1; for(int i=n;i>=0;i--){ for(int j=0;j<26;j++)nxt[i][j]=pos[j]; if(i)pos[s[i]-'a']=i; } int q;cin>>q; while(q--){ int l,r,mx=0; scanf("%d%d",&l,&r); int f[30][30]; memset(f,0x3f,sizeof f); for(int i=0;i<=m;i++)f[i][0]=l-1; for(int len=1;len<=m;len++){ for(int j=len;j<=m;j++){ f[j][len]=f[j-1][len]; if(f[j-1][len-1]<=r) f[j][len]=min(f[j][len],nxt[f[j-1][len-1]][t[j]-'a']); } } for(int i=1;i<=m;i++) if(f[m][i]<=r)mx=i; cout<<(r-l+1)+m-2*mx<<' '; } } }