跳过正文
  1. Posts/

hdu 2896 病毒侵袭 (ac自动机)

·2 分钟

hdu 2896 题目链接

题意:给出n个病毒,然后给出m个网站,然后问每个网站中有哪些病毒,以及有病毒的网站的个数。

需要注意病毒和网站都需要按从小到达排列输出。

思路:ac自动机,需要记录病毒id…然后。。因为病毒的id忘记排序wa了好多发。。智力减2.

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年08月16日 星期二 19时53分24秒
  4File Name :code/hdu/2896.cpp
  5************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <stack>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <deque>
 19#include <ctime>
 20#define fst first
 21#define sec second
 22#define lson l,m,rt<<1
 23#define rson m+1,r,rt<<1|1
 24#define ms(a,x) memset(a,x,sizeof(a))
 25typedef long long LL;
 26#define pi pair < int ,int >
 27#define MP make_pair
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33vector <int>ans;
 34struct Trie
 35{
 36    struct Node
 37    {
 38	Node *nxt[128];
 39	Node *fail;
 40	int val;
 41	Node()
 42	{
 43	    for ( int i = 0 ; i < 128 ; i++) nxt[i] = NULL;
 44	    val = 0;
 45	    fail = NULL;
 46	}
 47    };
 48    Node *root;
 49    void init()
 50    {
 51	root = new Node();
 52    }
 53    void Insert(char *s,int num)
 54    {
 55	int len = strlen(s);
 56	Node *u = root;
 57	for ( int i = 0 ; i < len ;i++)
 58	{
 59	    int v = s[i]-32;
 60	    if (u->nxt[v]==NULL) u->nxt[v] = new Node();
 61	    u = u->nxt[v];
 62	}
 63	u->val = num;
 64    }
 65    void getFail()
 66    {
 67	root->fail = root;
 68	queue<Node*>Q;
 69	for ( int i = 0 ; i < 128 ; i++)
 70	{
 71	    if (root->nxt[i]==NULL)
 72		root->nxt[i] = root;
 73	    else
 74	    {
 75		root->nxt[i]->fail = root;
 76		Q.push(root->nxt[i]);
 77	    }
 78	}
 79	while (!Q.empty())
 80	{
 81	    Node * cur = Q.front();
 82	    Q.pop();
 83	    for ( int i = 0 ; i < 128 ; i++)
 84		if (cur->nxt[i]==NULL)
 85		    cur->nxt[i] = cur->fail->nxt[i];
 86		else
 87		{
 88		    cur->nxt[i]->fail = cur->fail->nxt[i];
 89		    Q.push(cur->nxt[i]);
 90		}
 91	}
 92    }
 93    bool Search(char *s)
 94    {
 95	int len = strlen(s);
 96	Node *u = root;
 97	ans.clear();
 98	bool ok = false;
 99	for ( int i = 0 ; i < len ; i++)
100	{
101	    int v  = s[i]-32;
102	    u = u->nxt[v];
103	    Node *tmp = u;
104	    while (tmp!=root&&tmp->val>0)
105	    {
106		ans.push_back(tmp->val);
107//  		tmp->val = 0;
108		tmp = tmp->fail;
109		ok = true;
110	    }
111	}
112	return ok;
113    }
114}ac;
115int n,m;
116char str[10025];
117int main()
118{
119	#ifndef  ONLINE_JUDGE
120	freopen("code/in.txt","r",stdin);
121  #endif
122	while (~scanf("%d",&n))
123	{
124	    ac.init();
125	    for ( int i = 1 ; i <= n ; i++)
126	    {
127		scanf("%s",str);
128//		cout<<"str:"<<str<<endl;
129		ac.Insert(str,i);
130	    }
131	    ac.getFail();
132	    int tot = 0 ;
133	    scanf("%d",&m);
134	    for ( int i = 1 ; i <= m ; i++)
135	    {
136		scanf("%s",str);
137//		cout<<"i:"<<i<<" str:"<<str<<endl;
138		if (ac.Search(str))
139		{
140		    tot++;
141		    printf("web %d:",i);
142		    sort(ans.begin(),ans.end()); //要求按顺序
143		    int siz = ans.size();
144		    for ( int i = 0 ; i < siz; i ++)
145			printf(" %d",ans[i]);
146		    printf("\n");
147		}
148	    }
149	    printf("total: %d\n",tot);
150	}
151  #ifndef ONLINE_JUDGE
152  fclose(stdin);
153  #endif
154    return 0;
155}

相关文章

ac自动机模板by Lalatina (hdu 2222)

·1 分钟
orzorz 日常%学弟 华科的未来orz 1#include <cstdio> 2#include <cstring> 3 4using namespace std; 5 6struct tnode { 7 int s; 8 tnode *f, *w, *c[26]; 9} T[5000000], *Q[5000000]; 10int C; 11 12inline tnode *tnew() { 13 memset(T + C, 0, sizeof(tnode)); 14 return T + C++; 15} 16 17inline void AcaInsert(tnode *p, const char *s) { 18 while (*s) { 19 int u = *s - 'a'; 20 if (!p->c[u]) 21 p->c[u] = tnew(); 22 p = p->c[u]; 23 ++s; 24 } 25 ++p->s; 26} 27 28inline void AcaBuild(tnode *p) { 29 p->f = p->w = p; 30 int ql = 0; 31 for (int i = 0; i < 26; ++i) 32 if (p->c[i]) { 33 p->c[i]->f = p->c[i]->w = p; 34 Q[ql++] = p->c[i]; 35 } 36 for (int qf = 0; qf < ql; ++qf) 37 for (int i = 0; i < 26; ++i) 38 if (Q[qf]->c[i]) { 39 tnode *f = Q[qf]->f; 40 while (f != p && !f->c[i]) 41 f = f->f; 42 if (f->c[i]) { 43 Q[qf]->c[i]->f = f->c[i]; 44 Q[qf]->c[i]->w = f->c[i]->s ? f->c[i] : f->c[i]->w; 45 } 46 else 47 Q[qf]->c[i]->f = Q[qf]->c[i]->w = p; 48 Q[ql++] = Q[qf]->c[i]; 49 } 50} 51 52inline int AcaMatch(tnode *root, const char *s) { 53 int x = 0; 54 for (tnode *p = root; *s; ++s) { 55 while (p != root && !p->c[*s - 'a']) 56 p = p->f; 57 if (p->c[*s - 'a']) { 58 p = p->c[*s - 'a']; 59 for (tnode *q = p; q->s != -1; q = q->w) { 60 x += q->s; 61 q->s = -1; 62 } 63 } 64 } 65 return x; 66} 67 68char S[1000001]; 69 70int main() { 71 int tt; 72 scanf("%d", &tt); 73 while (tt--) { 74 C = 0; 75 tnode *root = tnew(); 76 root->s = -1; 77 int N; 78 scanf("%d", &N); 79 while (N--) { 80 scanf("%s", S); 81 AcaInsert(root, S); 82 } 83 AcaBuild(root); 84 scanf("%s", S); 85 printf("%d\n", AcaMatch(root, S)); 86 } 87 return 0; 88}

20160816随笔

·1 分钟
突然感觉。。。 我这种几乎没有恋爱经验的人。。。 感觉被妹子随便用点手段就能收了啊orz

poj 2001 Shortest Prefixes (trie树)

·2 分钟
poj 2001 题目链接 题意:给出n个字符串的表,问每个字符串的简化表示。简化表示的要求是,以该字符串的最短的而且不能产生歧义的前缀来表示。