题解 P2408 【不同子串个数】
Rorschachindark · · 题解
不同子串个数
题目传送门
思路
来一篇比较不一样的
考虑增加一个点之后,我们设
实测这种方法会比
\text {Code}
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define ll long long
#define MAXN 200005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int n;
char s[MAXN];
int lst = 1,node = 1;
int len[MAXN],fa[MAXN],ch[MAXN][26];
ll ans;
void Insert (int c){
int f = lst,q = ++ node;lst = q;
len[q] = len[f] + 1;
while (f && !ch[f][c]) ch[f][c] = q,f = fa[f];
if (!f) fa[q] = 1;
else{
int x = ch[f][c];
if (len[x] == len[f] + 1) fa[q] = x;
else{
int p = ++ node;
fa[p] = fa[x],len[p] = len[f] + 1;
memcpy (ch[p],ch[x],sizeof (ch[x]));
fa[x] = fa[q] = p;
while (f && ch[f][c] == x) ch[f][c] = p,f = fa[f];
}
}
ans += len[q] - len[fa[q]];
}
signed main(){
read (n);
scanf ("%s",s + 1);
for (Int i = 1;i <= n;++ i) Insert (s[i] - 'a');
write (ans),putchar ('\n');
return 0;
}