#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <queue&
Gt
using namespace Std; /** is an AC automaton but each word has two states, [0] can be overlap,[1] is not overlap times we use the last array to record the position of each word that cannot be overlap, if the current position-last[
Word] + 1 > strlen (Word), then prove that the word is not overlap, update the last array, corresponding to the number of +1 can complement, water problem.
* * Const int max_alphabet = 27;
const int max_text = 100010;
const int Max_word = 7;
const int max_word_num = 100010;
struct node {int id;
int cnt;
int Len;
node* fail;
node* Next[max_alphabet];
Node () {id =-1;//Specify the location where the word appears.
CNT = 0;
Fail = NULL;
len = 0;
memset (Next,0,sizeof (next));
}
};
int cnt;
int Loc[max_word_num];
int Type[max_word_num]; int strcnt[max_word_num][2]; Two states of each word int last[max_word_num];
The place where each word last appeared.
Queue<node*> Q;
Variable area end///int Ac_insert (node* root,char* dest,int flag) {node* tmp = root;
int L = strlen (dest); for (int i = 0; I &lT L
i++) {int k = dest[i]-' a ';
if (tmp->next[k] = = NULL) {Tmp->next[k] = new node ();
} TMP = tmp->next[k];
} if (tmp->id = = 1) {tmp->id = cnt;
cnt++; } tmp->cnt = tmp->cnt |
Flag
Tmp->len = l; Return tmp->id;
Indicate the first occurrence of the word in the word list ...
} void Ac_build (node* root) {root->fail = NULL;
Q.push (root);
while (!q.empty ()) {node* tmp = Q.front ();
Q.pop ();
Node *p;
for (int i = 0; i < 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 Ac_search (node* root,char* dest) {node* tmp;
Node* p;
p = root;
for (int i = 0; dest[i]; i++) {int ind = Dest[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-&G
T;id]) {strcnt[tmp->id][1]++;
Last[tmp->id] = i;
}} tmp = tmp->fail;
int main () {#ifndef Online_judge freopen ("b:\\acm\\summervacation\\string-i\\b.in", "R", stdin);
Freopen ("B:\\acm\\summervacation\\string-i\\b.out", "w", stdout);
#endif Char Dest[max_text];
Char Word[max_word];
int t = 1;
while (scanf ("%s", dest)!= 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] = Ac_insert (root,word,type[i]+1);
} ac_build (root);
Ac_search (root,dest);
printf ("Case%d\n", t++);
int ans; for (int i = 0; i < N; i++) {As = strcnt[loc[i]][type[i]];
printf ("%d\n", ans);
printf ("\ n");
#ifndef Online_judge fclose (stdin);
Fclose (stdout);
#endif return 0;
}