【ZOJ】3430 Detect the Virus

动态建树MLE。模仿别人的代码模板各种原因wa后,终于AC。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6 
  7 #define MAXN  515*70
  8 #define NXTN  256
  9 
 10 bool visit[515];
 11 char str[3005];
 12 unsigned char buf[2050], src[3005];
 13 
 14 typedef struct {
 15     int next[MAXN][NXTN], fail[MAXN], v[MAXN];
 16     int root, n;
 17     void init() {
 18         n = 0;
 19         root = newNode();
 20     }
 21     int newNode() {
 22         for (int i=0; i<NXTN; ++i)
 23             next[n][i] = -1;
 24         v[n] = 0;
 25         return n++;
 26     }
 27     void create(unsigned char s[], int len, int in) {
 28         int i = 0, cur = root, tmp;
 29 
 30         while (i < len) {
 31             if (next[cur][s[i]] == -1) {
 32                 tmp = newNode();
 33                 next[cur][s[i]] = tmp;
 34             }
 35             cur = next[cur][s[i]];
 36             ++i;
 37         }
 38         v[cur] = in;
 39     }
 40     void build() {
 41         int i, cur;
 42         queue<int> que;
 43 
 44         fail[root] = root;
 45         for (i=0; i<NXTN; ++i) {
 46             if (next[root][i] == -1) {
 47                 next[root][i] = root;
 48             } else {
 49                 fail[next[root][i]] = root;
 50                 que.push(next[root][i]);
 51             }
 52         }
 53 
 54         while (!que.empty()) {
 55             cur = que.front();
 56             que.pop();
 57             for (i=0; i<NXTN; ++i) {
 58                 if (next[cur][i] == -1) {
 59                     next[cur][i] = next[fail[cur]][i];
 60                 } else {
 61                     fail[next[cur][i]] = next[fail[cur]][i];
 62                     que.push(next[cur][i]);
 63                 }
 64             }
 65         }
 66     }
 67     void query(unsigned char s[], int len) {
 68         int i = 0, cur = root, tmp;
 69 
 70         memset(visit, false, sizeof(visit));
 71         while (i < len) {
 72             cur = next[cur][s[i]];
 73             tmp = cur;
 74             while (tmp != root) {
 75                 visit[v[tmp]] = true;
 76                 tmp = fail[tmp];
 77             }
 78             ++i;
 79         }
 80     }
 81 } AC;
 82 
 83 void output(int n) {
 84     int ans = 0;
 85     for (int i=1; i<=n; ++i)
 86         if (visit[i])
 87             ++ans;
 88     printf("%d
", ans);
 89 }
 90 
 91 unsigned char getVal(char c) {
 92     if (c>='A' && c<='Z')
 93         return c - 'A';
 94     if (c>='a' && c<='z')
 95         return c - 'a' + 26;
 96     if (c>='0' && c<='9')
 97         return c - '0' + 52;
 98     if (c == '+') return 62;
 99     return 63;
100 }
101 
102 int decode(unsigned char src[], int len) {
103     int i, k = 0;
104 
105     for (i=0; i<len; i+=4) {
106         buf[k++] = (src[i]<<2)+(src[i+1]>>4);
107         if (i+2 < len)
108             buf[k++] = (src[i+1]<<4) + (src[i+2]>>2);
109         if (i+3 < len)
110             buf[k++] = (src[i+2]<<6) + (src[i+3]);
111     }
112     return k;
113 }
114 
115 AC ac;
116 
117 int main() {
118     int i, j, l, n, m;
119 
120 
121     while (scanf("%d", &n) != EOF) {
122         ac.init();
123         for (i=1; i<=n; ++i) {
124             scanf("%s", str);
125             for (j=0; str[j]&&str[j]!='='; ++j) {
126                 src[j] = getVal(str[j]);
127             }
128             l = decode(src, j);
129             ac.create(buf, l, i);
130         }
131         ac.build();
132         scanf("%d", &m);
133         while (m--) {
134             scanf("%s", str);
135             for (j=0; str[j]; ++j) {
136                 if (str[j] == '=')
137                     break;
138                 src[j] = getVal(str[j]);
139             }
140             l = decode(src, j);
141             ac.query(buf, l);
142             output(n);
143         }
144         printf("
");
145     }
146 
147     return 0;
148 }
原文地址:https://www.cnblogs.com/bombe1013/p/3821106.html