给定一个长为 的字符串 ,一些位置被标记为不可用。
找到一个子串, 最大,合法出现次数是指endpos不在不可用位置上的出现次数。
求最大的 。
令不合法的位置不产生cnt的贡献即可,SAM模板掌握题,既然写题意了就发出来吧。
/* LittleFall : Hello! */
#include <bits/stdc++.h>
using namespace std; using ll = long long; inline int read();
const int M = 200016, MOD = 1000000007;
int sz, lst; //后缀自动机大小,上一次插入的节点
int ch[M<<1][26], len[M<<1], link[M<<1], cnt[M<<1];
void extend(const char *s, const char *ban)
{
for(int i=0; s[i]; ++i)
{
int c = s[i]-'a';
int cur = ++sz;
len[cur] = len[lst] + 1;
int p = lst;
while(!ch[p][c])
{
ch[p][c] = cur;
p = link[p];
}
if(ch[p][c] != cur)
{
int q = ch[p][c];
if(len[p] + 1 == len[q]) link[cur] = q;
else
{
int clone = ++sz;
memcpy(ch[clone], ch[q], sizeof(ch[q]));
link[clone] = link[q];
len[clone] = len[p]+1;
while(ch[p][c]==q)
{
ch[p][c] = clone;
p = link[p];
}
link[q] = link[cur] = clone;
}
}
lst = cur;
cnt[cur] += (ban[i]=='0');
}
vector<int> nodes;
for(int i=1; i<=sz; ++i)
nodes.push_back(i);
sort(nodes.begin(), nodes.end(), [&](int a, int b){
return len[a]>len[b];
});
for(auto u:nodes)
cnt[link[u]] += cnt[u];
}
char str[M], ban[M];
int main(void)
{
#ifdef _LITTLEFALL_
freopen("in.txt","r",stdin);
#endif
read();
scanf("%s %s", str, ban);
extend(str, ban);
ll ans = 0;
for(int i=1; i<=sz; ++i)
{
ans = max(ans, 1ll*cnt[i]*len[i]);
}
cout << ans << "\n";
return 0;
}
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}