RT.
写法是二分长度,然后算出需要的长度,维护每个字母后缀出现次数、位置。
WA 31 个点。
代码极其丑陋/kk
int n;
i128 m,k,suf[100010][26],id[26][100010],cnt[26];
string s,t;
bool check(i128 x)
{
// cout<<" "<<(int)x<<endl;
i128 c=0;
for(int i=0;i<k;i++)
{
// cout<<" "<<(int)c<<endl;
i128 p=t[i]-'a';
i128 d=suf[c%m][p];
// cout<<" "<<i<<" "<<(int)d<<" "<<(int)c<<endl;
if(d>=x)
{
i128 l=c/m*m;
c=l+id[p][d-x+1]+1;
if(c>n*m)return 0;
}
else
{
// cout<<" "<<(int)c<<endl;
c=c/m*m+m;
// cout<<" "<<(int)c<<endl;
// if(c>n*m)return 0;
int px=x;
px-=d;
i128 ca=suf[0][p];
if(!ca)return 0;
i128 lt=px/ca;
// cout<<" "<<(int)lt<<endl;
if(px%ca==0)
{
c+=m*(lt-1);
// c-=m;
// cout<<" "<<(int)c<<" "<<(int)(m*(lt-1))<<endl;
if(c>n*m||lt-1>n)return 0;
// cout<<" "<<(int)c<<" "<<(int)id[p][1]<<endl;
c+=id[p][1]+1;
if(c>n*m)return 0;
continue;
}
c+=m*lt;
if(c>n*m||lt>n)return 0;
c+=id[p][ca-px%ca];
if(c>n*m)return 0;
c++;
if(c>n*m)return 0;
}
// cout<<" "<<(int)x<<" "<<(int)i<<" "<<(int)c<<endl;
}
return c<=n*m;
}
void main_solve(int test_id)
{
cin>>n>>s>>t;
m=s.size();
k=t.size();
int l=1,r=n*m/k,ans=0;
for(int i=m-1;i>=0;i--)
{
for(int j=0;j<26;j++)
suf[i][j]=suf[i+1][j]+(s[i]-'a'==j);
id[s[i]-'a'][++cnt[s[i]-'a']]=i;
}
while(l<=r)
{
int mid=l+r>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans;
return;
}