定义:
CH 取数据范围
const int NODE = 105 , CH = 4 ,mod = 100000;
int ch[NODE][CH], val[NODE] ,sz , fail[NODE];
初始化:
只要清空ch[0],注意sz是从1开始;
void init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
插入:
void insert(char *s)
{
int u=0;
for(;*s;s++)
{
int c=idx(*s);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=1;
}
重头戏:
int queue[MAXN];
void getfail()
{
int *rear=queue,*front=queue;
for(int c=0;c<CH;c++)
{
int u=ch[0][c];
if(u)
*rear++=u,f[u]=0,last[u]=0;
}
while(rear!=front)
{
int cur = front++;
for(int c=0;c<CH;c++)
{
int &u = ch[cur][c];
int tf=ch[f[cur]][c];
if(!u)
{
u=tf;
continue;
}
f[u]=tf;
last[u]=val[f[u]]?f[u]:last[f[u]];
*rear++=u;
}
}
}
接下来就是询问..
int find(char *s)
{
int sum=0;
int u=0;
for(;*s;s++)
{
int c=idx(*s);
u=ch[u][c];
int next=0;
if(val[u])
next=u;
else if(last[u])
next=last[u];
for(int tmp=next;tmp;tmp=last[tmp])
sum+=val[tmp];
}
return sum;
}