SAM学习笔记

按照hihocoder上的SAM的教程学习了一波SAM

http://hihocoder.com/contest/hiho127

http://hihocoder.com/contest/hiho128

http://hihocoder.com/contest/hiho129

http://hihocoder.com/contest/hiho130

http://hihocoder.com/contest/hiho131

http://hihocoder.com/contest/hiho132

http://hihocoder.com/contest/hiho133

搞了这么多年ACM终于会一个字符串算法了


模版:

namespace SAM
{
	const int CHAR=26;
	const int MAXN=1e6+5;
	struct SAM_Node
	{
		SAM_Node *fa,*next[CHAR];
		int mx,mi;//当前状态下最长的子串和最短的子串
		int id;
		SAM_Node(){}
		SAM_Node(int _mx)
		{
			fa=0;
			mx=_mx;
			memset(next,0,sizeof(next));
		}
	};
	SAM_Node SAM_node[MAXN*2],*SAM_root,*SAM_last;
	int SAM_size;
	SAM_Node *newSAM_Node(int len)
	{
		SAM_node[SAM_size]=SAM_Node(len);
		SAM_node[SAM_size].id=SAM_size;
		return &SAM_node[SAM_size++];
	}
	SAM_Node *newSAM_Node(SAM_Node *p)
	{
		SAM_node[SAM_size]=*p;
		SAM_node[SAM_size].id=SAM_size;
		return &SAM_node[SAM_size++];
	}
	void SAM_init()
	{
		SAM_size=0;
		SAM_root=SAM_last=newSAM_Node(0);
	}
	void SAM_add(int c)
	{
		SAM_Node *u=SAM_last,*z=newSAM_Node(u->mx+1);
		SAM_last=z;
		for(;u&&!u->next[c];u=u->fa)
			u->next[c]=z;
		if(!u)
		{
			z->fa=SAM_root;
			z->mi=1;
			return;
		}
		SAM_Node *x=u->next[c];
		if(x->mx==u->mx+1)//不用拆分
		{
			z->fa=x;
			z->mi=x->mx+1;
			return;
		}
		SAM_Node *y=newSAM_Node(x);//拆分x
		y->mx=u->mx+1;
		x->fa=y;x->mi=y->mx+1;
		z->fa=y;z->mi=y->mx+1;
		for(;u&&u->next[c]==x;u=u->fa)
			u->next[c]=y;
		y->mi=y->fa->mx+1;
	}
	void SAM_build(char *s)
	{
		SAM_init();
		int len=strlen(s);
		for(int i=0;i<len;i++)
			SAM_add(s[i]-'a');
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值