#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define LNF 0x3f3f3f3f3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) const double pi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=4e5+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; const int maxp=26+5; using namespace std; struct Suffix_Node{ int ch[maxp],par,len; void init(){ NEW(ch,0); par=len=0; } }; class Suffix_Automation{ private: Suffix_Node s[maxn]; int cur,las,siz,crp; public: Suffix_Automation():las(1),cur(1),siz(1),crp(1){} const void init(){ for(int i=0;i<=siz;i++) s[i].init(); las=cur=siz=crp=1; } const int match(const char c)const{ return s[crp].ch[c-'a']; } const void withdraw(const int len){ while(crp!=0&&s[s[crp].par].len>=len) crp=s[crp].par; if(crp==0) crp=1; } const void Transfer(const int len,const char c){ crp=s[crp].ch[c-'a']; if(crp==0) crp=1; withdraw(len); } const void ex_tend(const char c){//扩展新字符 int x=c-'a'; cur=++siz; s[cur].len =s[las].len+1; while(las!=0&&!s[las].ch[x]) s[las].ch[x]=cur,las=s[las].par; if(las==0) s[cur].par=1; else{ int q,nq; q=s[las].ch[x]; if(s[q].len==s[las].len+1) s[cur].par=q; else{ Nq = ++ siz; s [nq] = s [q], s [nq] .LEN = s [ t ] .LEN + 1 ; s [cur] .par = s [q] .par = nq; while (the =! 0 && s [the] .ch [x] == q) s [the] .ch [x] = nq, the = s [the] .par; } } The = cur; } } SAM;