HDU 4622 本质不同的子串个数:后缀自动机

题意:给出一个串,每次求一个子串[ l , r ]。问这个串中,本质不同的子串个数,多组询问,数据小。


题解:记住SAM是ON的。所以直接对每个[ l , r ]建SAM,然后建完就出答案。时间足够用。模板题为什么要写博客呢。。。。因为复用自动机的话。。要清空呀。。。。


Code:

#include
using namespace std;
const int maxn = 2e3+100;
char s[maxn];
int len;
int T;
struct SAM{
	int last,cnt,nxt[maxn*2][26],fa[maxn*2],l[maxn*2];
	int ans;
	void init(){
		last = cnt=1;
		memset(nxt[1],0,sizeof nxt[1]);
		fa[1]=0;ans=0;l[1]=0;
	}
	int inline newnode(){
		++cnt;
		memset(nxt[cnt],0,sizeof nxt[cnt]);
		fa[cnt]=l[cnt]=0;
		return cnt;
	}
	void add(int c){
		int p = last;
		int np = newnode();
		last = np;
		l[np] = l[p]+1;
		while (p&&!nxt[p][c]){
			nxt[p][c]=np;
			p = fa[p];
		}
		if (!p){
			fa[np]=1;
		}else{
			int q = nxt[p][c];
			if (l[q]==l[p]+1){
				fa[np] = q;
			}else{
				int nq = newnode();
				memcpy(nxt[nq],nxt[q],sizeof nxt[q]);
				fa[nq] = fa[q];
				l[nq] = l[p]+1;
				fa[np]=fa[q]=nq;
				while (nxt[p][c]==q){
					nxt[p][c]=nq;
					p=fa[p];
				}
			}
		}
//		cout<


你可能感兴趣的:(HDU)