http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/D
0状态时就是模板,1时判断一下后匹配的位置减前面的距离是不是大于当前单词的距离
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
const int MAX=100010;
struct node
{
int id;
int cnt;
int len;
node* fail;
node* next[27];
node()
{
id=-1;
cnt=0;
fail=NULL;
len=0;
memset(next,0,sizeof(next));
}
};
int cnt;
int loc[MAX];
int type[MAX];
int strcnt[MAX][2]; // 每个词两个状态
int last[MAX]; //每个词最后一次出现的地方。
queue<node*>q;
int insert(node* root,char *str,int flag)
{
node *tmp=root;
int l=strlen(str);
for(int i=0;i<l;i++)
{
int p=str[i]-'a';
if(tmp->next[p]==NULL)tmp->next[p]=new node();
tmp=tmp->next[p];
}
if(tmp->id==-1)
{
tmp->id=cnt;
cnt++;
}
tmp->cnt=tmp->cnt|flag;
tmp->len=l;
return tmp->id;
}
void build_ac(node* root)
{
root->fail=NULL;
q.push(root);
while(!q.empty())
{
node *tmp=q.front();
q.pop();
node *p;
for(int i=0;i<26;i++)
{
if(tmp->next[i])
{
if(tmp==root)tmp->next[i]->fail=root;
else
{
p=tmp->fail;
while(p)
{
if(p->next[i])
{
tmp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(!p)
tmp->next[i]->fail=root;
}
q.push(tmp->next[i]);
}
}
}
}
void query(node* root,char* str)
{
node* tmp;
node* p;
p=root;
for(int i=0;str[i];i++)
{
int ind=str[i]-'a';
while(p->next[ind]==NULL&&p!=root)
p=p->fail;
p=p->next[ind];
if(p==NULL)
p=root;
tmp=p;
while(tmp!=NULL)
{
if(tmp->id!=-1)
{
if(tmp->cnt&1)strcnt[tmp->id][0]++;
if(tmp->cnt&2)
if(i-tmp->len+1>last[tmp->id])
{
strcnt[tmp->id][1]++;
last[tmp->id]=i;
}
}
tmp=tmp->fail;
}
}
}
void free_(node *r)
{
for(int i=0;i<26;i++)
{
if(r->next[i])
free_(r->next[i]);
}
free(r);
}
int main()
{
char str[100010];
char word[10];
int t=1;
while(scanf("%s",str) != EOF)
{
memset(last,-1,sizeof(last));
memset(strcnt,0,sizeof(strcnt));
cnt=1;
node *root=new node();
int N;
scanf("%d",&N);
for(int i = 0 ; i < N ; i++)
{
scanf("%d %s",&type[i],word);
loc[i] = insert(root,word,type[i]+1);
}
build_ac(root);
query(root,str);
printf("Case %d\n",t++);
int ans;
for(int i = 0 ; i < N ; i++)
{
ans = strcnt[loc[i]][type[i]];
printf("%d\n",ans);
}
printf("\n");
free_(root);
}
return 0;
}