您的位置:首页 > 其它

后缀自动机模板 SAM

2017-09-13 17:21 393 查看

一点疑问:

  当创建nq节点时,要不要把nq的cnt标记赋值为1?

  讲道理nq节点也是代表一个子串啊,不过网上的模板都没赋值。

2017.9.18 update:

  把memset部分重写,改成用节点用到时再初始化,初始化所有节点可能被卡。

  fa,len,cnt数组其实不用清空,因为用时都赋值了。

struct SAM
{
static const int MAXN = 300001<<1;//大小为字符串长度两倍
static const int LetterSize = 26;

int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组

void init( void)
{
last = tot = 1;
len[1] = 0;
memset( ch[1], 0, sizeof ch[1]);
}

void add( int x)
{
int p = last, np = last = ++tot;
len[np] = len

+ 1, cnt[last] = 1; memset( ch[np], 0, sizeof ch[np]); while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } void toposort( void) { for(int i = 1; i <= len[last]; i++) sum[i] = 0; for(int i = 1; i <= tot; i++) sum[len[i]]++; for(int i = 1; i <= len[last]; i++) sum[i] += sum[i-1]; for(int i = 1; i <= tot; i++) tp[sum[len[i]]--] = i; for(int i = tot; i; i--) cnt[fa[tp[i]]] += cnt[tp[i]]; } } sam;

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: