写了一个后缀自动机,一开始用的 unordered_map 存转移边,有一个点 TLE 了,然后改成 map 就对了。请问这是为什么啊?(我以前一直以为 unordered_map 比 map 快,只是不是有序的)
提交记录:
map:https://www.luogu.com.cn/record/160374810
unordered_map:https://www.luogu.com.cn/record/160374431
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
namespace IO
{
int read()
{
int f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-') f = - 1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0';
c = getchar();
}
return f * x;
}
void write(int x)
{
if(x < 0){
putchar('-');
x = - x;
}
if(x > 9) write(x / 10);
putchar(x % 10 + '0');
}
}
using namespace IO;
// Fast IO sometimes -> Slow IO
const int N = 1e5;
struct SAM{
int ed, lst;
ll sum;
int len[2 * N - 1 + 1 + 1];
int fa[2 * N - 1 + 1 + 1];
map < int, int > ch[2 * N - 1 + 1 + 1]; // 用 unordered_map 会 TLE 一个点,用 map 可以 AC,不知道为什么。
void Init()
{
ed = 1;
lst = ed;
sum = 0ll;
}
ll Insert(int c)
{
int p = lst, np = ++ ed;
lst = np;
len[np] = len[p] + 1;
while(p && ! ch[p][c]){
ch[p][c] = np;
p = fa[p];
}
if(! p){
fa[np] = 1;
sum += 1ll * (len[np] - len[fa[np]]);
return sum;
}
int q = ch[p][c];
if(len[q] == len[p] + 1){
fa[np] = q;
sum += 1ll * (len[np] - len[fa[np]]);
return sum;
}
int nq = ++ ed;
len[nq] = len[p] + 1; //
ch[nq] = ch[q];
while(p && ch[p][c] == q){
ch[p][c] = nq;
p = fa[p];
}
fa[nq] = fa[q];
sum += 1ll * (len[nq] - len[fa[nq]]);
sum -= 1ll * (len[q] - len[fa[q]]);
fa[q] = nq;
sum += 1ll * (len[q] - len[fa[q]]);
fa[np] = nq;
sum += 1ll * (len[np] - len[fa[np]]);
return sum;
}
}sam;
void solve()
{
int n = read();
vector < int > a(n + 1);
for(int i = 1; i <= n; i ++) a[i] = read();
sam.Init();
for(int i = 1; i <= n; i ++) printf("%lld\n", sam.Insert(a[i]));
}
signed main()
{
int t = 1;
while(t --) solve();
return 0;
}