对于这道模板题我们先看看代码:
#include
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = N<<2;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {
read(first);
read(args...);
}
struct SAM {
int ch[30];
int fa, len;
}node[maxn];
int tot = 1, las = 1;
vector<int> G[maxn];
ll ans;
ll num[maxn];
// p 是上次最后的点,np是当前点
void add(int c) {
int p = las, np = ++ tot;
num[tot] = 1; // 注意我们这里是对SAM里面的终止节点进行设置成1
las = np;
node[np].len = node[p].len + 1;
for(;p&&!node[p].ch[c]; p = node[p].fa) node[p].ch[c] = np;
if(!p) node[np].fa = 1;
else {
int v = node[p].ch[c];
if(node[v].len == node[p].len + 1) node[np].fa = v;
else {
int nv = ++ tot;
node[nv] = node[v];
node[nv].len = node[p].len + 1;
for(;p&&node[p].ch[c] == v; p = node[p].fa) node[p].ch[c] = nv;
node[np].fa = node[v].fa = nv;
}
}
}
inline void dfs(int u) {
for(auto it : G[u]) {
dfs(it);
num[u] += num[it];
}
if(num[u] != 1) ans = max(ans,1ll*num[u]*node[u].len);
}
int main() {
IOS;
string s;
cin >> s;
for(int i = 0; i < s.length(); ++ i)
add(s[i]-'a');
for(int i = 2; i <= tot; ++ i)
G[node[i].fa].push_back(i);
dfs(1);
cout << ans;
}