[洛谷P2408]不同子串个数
题目大意:给你一个字符串,求其中本质不同的字串的个数
题解:同[洛谷P4070][SDOI2016]生成魔咒,只要最后再输出就行了
卡点:无
C++ Code:
#include <cstdio>
#include <map>
#define maxn 100010
long long ans;
namespace SAM {
#define N (maxn << 1)
#define root 1
int R[N], fail[N];
int nxt[N][26];
int lst = root, idx = root;
void append(char __ch) {
int ch = __ch - 'a';
int p = lst, np = lst = ++idx;
R[np] = R[p] + 1;
for (; p && !nxt[p][ch]; p = fail[p]) nxt[p][ch] = np;
if (!p) fail[np] = root;
else {
int q = nxt[p][ch];
if (R[p] + 1 == R[q]) fail[np] = q;
else {
int nq = ++idx;
std::copy(nxt[q], nxt[q] + 26, nxt[nq]);
fail[nq] = fail[q], R[nq] = R[p] + 1, fail[np] = fail[q] = nq;
for (; p && nxt[p][ch] && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq;
}
}
}
int query() {
return R[lst] - R[fail[lst]];
}
#undef root
#undef N
}
#define maxn 100010
int n;
char s[maxn];
int main() {
scanf("%d%s", &n, s);
for (int i = 0; i < n; i++) {
SAM::append(s[i]);
ans += SAM::query();
}
printf("%lld\n", ans);
return 0;
}

浙公网安备 33010602011771号