HDU-2896 病毒侵袭 && HDU-3065 病毒侵袭持续中(AC自动机)

来源:互联网 发布:Ubuntu 安装 login 编辑:程序博客网 时间:2024/05/22 13:09

HDU-2896

注意数组范围。

#include<iostream>#include<cstdio>#include<cstring>#include<string>using namespace std;const int N = 3000005;const int Letters = 95;//不能开大了,不然会MLE/*注意这些细节127-32 = 95,我竟然因为开到了135而爆了内存,长个教训,以后先估值*/char str[10005], keyword[205];int flag[505];int head, tail;struct Trie{    Trie *fail;    Trie *next[Letters];    int count;    Trie() //init    {        fail = NULL;        count = 0;        memset(next,0,sizeof(next));        //for(int i = 0; i < Letters; ++i)            //next[i] = NULL;    }}*q[N];Trie *root;void Insert(char *str,int num) //??Trie{    int temp, len;    Trie *p = root;    len = strlen(str);    for(int i = 0; i < len; ++i)    {        temp = str[i] - 32;        if(p->next[temp] == NULL)            p->next[temp] = new Trie();        p = p->next[temp];    }    p->count = num;}void Build_ac() //???fail???BFS{    root->fail = NULL;    q[tail++] = root;    Trie *p,*temp;    while(head != tail)    {        p = q[head++]; //????        temp = NULL;        for(int i = 0; i < Letters; ++i)        {            if(p->next[i] != NULL)            {                if(p == root) //?????fail????                    p->next[i]->fail = root;                else                {                    temp = p->fail; //????                    while(temp != NULL) //2??????????or????                    {                        if(temp->next[i] != NULL) //????                        {                            p->next[i]->fail = temp->next[i];                            break;                        }                        temp = temp->fail;                    }                    if(temp == NULL) //???????                        p->next[i]->fail = root;                }                q[tail++] = p->next[i]; //??            }        }    }}int Query() //??{    int index, len, result = 0;    Trie *p = root; //Tire??    len = strlen(str);    for(int i = 0; i < len; ++i)    {        index = str[i] - 32;        while(p->next[index] == NULL && p != root) //??????            p = p->fail;        p = p->next[index];        if(p == NULL)            p = root;        Trie *temp = p; //p???temp?????        while(temp != root )        {            flag[temp->count] = 1;            if(temp->count != 0)                result++;            temp = temp->fail;        }    }    return result;}int main(){    int n,m;    while(~scanf("%d",&n))    {        head = tail = 0;        root = new Trie();        getchar();        for(int i = 1; i <= n; ++i)        {            gets(keyword);            Insert(keyword,i);        }        Build_ac();        scanf("%d",&m);        int sum = 0;//??        for(int i = 1;i <= m;i++)        {            memset(flag,0,sizeof(flag));            scanf("%s", str);            if(Query())            {                printf("web %d:",i);                sum++;                for(int j = 1;j <= n;j++)                    if(flag[j])                        printf(" %d",j);                printf("\n");            }        }        printf("total: %d\n",sum);    }    return 0;}

HDU-3065

和上面的题类似,然而我却一直wa,最后胡改才ac了。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N = 500005;const int Letters = 26;char s[1005][55],str[2000015];int flag[1005];inline int idx(char c){return c-'A';}struct Trie{    int count;    Trie *fail;    Trie *next[Letters];    Trie()    {        count = 0;        fail = NULL;        memset(next,0,sizeof(next));    }}*q[N];int head,tail;Trie *root;void Insert(char *word, int num){Trie *p = root;int i = 0, index;while(word[i]){index = idx(word[i]);if(p->next[index] == NULL)p->next[index] = new Trie();p = p->next[index];i++;}p->count = num;}void Build_ac(){int i;root->fail = NULL;q[tail++] = root;while(head != tail){Trie *temp = q[head++];Trie *p = NULL;for(int i = 0; i < Letters; i++){if(temp->next[i]){if(temp == root)temp->next[i]->fail = root;else{p = temp->fail;while(p != NULL){if(p->next[i] != NULL){temp->next[i]->fail = p->next[i];break;}p = p->fail;}if(p == NULL)temp->next[i]->fail = root;}q[tail++] = temp->next[i];}}}}void Query(){int i = 0, index;Trie *p = root;while(str[i]){if(str[i] < 'A' || str[i] > 'Z'){p = root;i++;continue;}index = str[i] - 'A';while(p->next[index] == NULL && p != root)p = p->fail;p = p->next[index];p = (p==NULL)?root:p;Trie *temp = p;while(temp != root && temp->count != 0){flag[temp->count] ++;temp = temp->fail;}i++;}}int main(){int n;while(~scanf("%d", &n)){head = tail = 0;root = new Trie();getchar();for(int i = 1; i <= n; i++){gets(s[i]);flag[i] = 0;Insert(s[i],i);}Build_ac();gets(str);Query();for(int i = 1; i <= n; i++){if(flag[i]){printf("%s: %d\n", s[i],flag[i]);}}}return 0;}



0 0
原创粉丝点击