题解 虚空恶魔
考试的时候以为切入点应该是在sam上维护不相交子串,于是不会做
写了个暴力还忘删调试了
其实这题只需要找到两个不相交的相同子串
维护出endpos集合中的最小值和最大值就可以了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 2000010
#define ll long long
//#define int long long
int n;
ll ans;
char s[N];
int len[N<<1], fail[N<<1], tr[N<<1][26], lft[N<<1], rit[N<<1], now, tot;
void init() {now=tot=0; memset(lft, 127, sizeof(lft)); for (int i=0; i<26; ++i) tr[0][i]=0; fail[0]=-1;}
void insert(char c, int pos) {
c-='a';
int cur=++tot;
for (int i=0; i<26; ++i) tr[cur][i]=0;
len[cur]=len[now]+1;
int p, q;
for (p=now; ~p&&!tr[p][c]; tr[p][c]=cur,p=fail[p]);
if (p==-1) fail[cur]=0;
else if (len[q=tr[p][c]]==len[p]+1) fail[cur]=q;
else {
int cln=++tot;
len[cln]=len[p]+1;
fail[cln]=fail[q];
for (int i=0; i<26; ++i) tr[cln][i]=tr[q][i];
for (; ~p&&tr[p][c]==q; tr[p][c]=cln,p=fail[p]);
fail[cur]=fail[q]=cln;
}
now=cur;
lft[cur]=rit[cur]=pos;
}
namespace force{
void solve() {
init();
insert(s[1], 1);
for (int i=2; i<=n; ++i) {
// cout<<"i: "<<i<<endl;
for (int j=i,u=0,l=0; j<=n; ++j) {
while (~u&&!tr[u][s[j]-'a']) u=fail[u], l=len[u];
if (u==-1) u=l=0;
else u=tr[u][s[j]-'a'], ans=max(ans, 1ll*(i-1)*(++l));
}
insert(s[i], i);
}
reverse(s+1, s+n+1);
init();
insert(s[1], 1);
for (int i=2; i<=n; ++i) {
// cout<<"i: "<<i<<endl;
for (int j=i,u=0,l=0; j<=n; ++j) {
while (~u&&!tr[u][s[j]-'a']) u=fail[u], l=len[u];
if (u==-1) u=l=0;
else u=tr[u][s[j]-'a'], ans=max(ans, 1ll*(i-1)*(++l));
}
insert(s[i], i);
}
printf("%lld\n", ans);
exit(0);
}
}
namespace task{
int deg[N<<1], tem[N<<1];
void solve() {
init();
for (int i=1; i<=n; ++i) insert(s[i], i);
for (int i=1; i<=tot; ++i) ++deg[len[i]];
for (int i=1; i<=tot; ++i) deg[i]+=deg[i-1];
for (int i=1; i<=tot; ++i) tem[deg[len[i]]--]=i;
for (int i=tot,t; i; --i) {
t=tem[i];
lft[fail[t]]=min(lft[fail[t]], lft[t]);
rit[fail[t]]=max(rit[fail[t]], rit[t]);
if (lft[t]<=rit[t]-len[t]) ans=max(ans, max(1ll*(rit[t]-len[t])*len[t], 1ll*len[t]*(n-lft[t])));
}
printf("%lld\n", ans);
exit(0);
}
}
signed main()
{
scanf("%s", s+1);
n=strlen(s+1);
// force::solve();
task::solve();
return 0;
}