zoukankan      html  css  js  c++  java
  • POJ 4052 Hrinity [AC自动机]

      跟2010福州的现场赛那题基本一样的,只是多了个去重。。上半年在金华邀请赛的时候还不会AC自动机,今天突然想起来就找出来写了一下。。数据给的很大,不过空间给的也是巨大=。=

      解码后就是裸的自动机,把包含的串标记一下,再用自动机找这些串的子串去重即可。

     1 #include <string.h>
     2 #include <stdio.h>
     3 #define MAXN 3000000
     4 int cas, n;
     5 int pos, next[MAXN][26], fail[MAXN], id[MAXN], flag[MAXN];
     6 char s[MAXN*2], ss[MAXN*2], sss[2600][1200];
     7 char *trans(char *ss, char *s){
     8     int len = 0, pp = 0;
     9     for (int i = 0; s[i]; i++) {
    10         if(s[i] == '[' || s[i] == ']')pp = 0;
    11         else if(s[i] >= '0' && s[i] <= '9')pp = pp*10+s[i]-'0';
    12         else if(s[i] >= 'A' && s[i] <= 'Z'){
    13             if (pp == 0) ss[len++] = s[i];
    14             else while (pp--) ss[len++] = s[i];
    15         }
    16     }
    17     ss[len] = '\0';
    18     return ss;
    19 }
    20 int newnode(){
    21     memset(next[pos], 0, sizeof next[pos]);
    22     id[pos] = -1, fail[pos] = flag[pos] = 0;
    23     return pos++;
    24 }
    25 void insert(char *s, int ids){
    26     int p = 0;
    27     for (int i = 0; s[i]; i++) {
    28         int &x = next[p][s[i] - 'A'];
    29         p = x ? x : x = newnode();
    30     }
    31     id[p] = ids;
    32 }
    33 int q[MAXN], front, rear;
    34 void makefail(){
    35     q[front = rear = 0] = 0,rear++;
    36     while (front < rear) {
    37         int u = q[front++];
    38         for (int i = 0; i < 26; i++) {
    39             int v = next[u][i];
    40             if (v) q[rear++] = v;
    41             else next[u][i] = next[fail[u]][i];
    42             if (v&&u) fail[v] = next[fail[u]][i];
    43         }
    44     }
    45 }
    46 int vis[3000];
    47 void removestr(int ids, char *s){
    48     for (int i = 0, p = 0; s[i]; i++){
    49         p = next[p][s[i]-'A'];
    50         for (int j = p; j; j = fail[j]){
    51             if (id[j] >= 0 && ids != id[j]) vis[id[j]] = 0;
    52         }
    53     }
    54 }
    55 int makeans(char *s){
    56     memset(vis, 0, sizeof vis);
    57     for (int i = 0, p = 0; s[i]; i++){
    58         p = next[p][s[i]-'A'];
    59         for (int j = p; j && flag[j] != -1; j = fail[j]){
    60             if (id[j] >= 0) vis[id[j]] = 1;
    61             flag[j] = -1;
    62         }
    63     }
    64     for (int i = 0; i < n; i++) if(vis[i] == 1) removestr(i, sss[i]);
    65     int ans = 0;
    66     for (int i = 0; i < n; i++) if(vis[i] == 1) ans ++;
    67     return ans;
    68 }
    69 int main(){
    70     //freopen("test.in", "r", stdin);
    71     scanf("%d", &cas);
    72     while (cas--) {
    73         scanf("%d", &n);
    74         pos = 0; newnode();
    75         for (int i = 0; i < n; i++) {
    76             scanf("%s", s);
    77             trans(sss[i], s);
    78             insert(sss[i], i);
    79         }
    80         makefail();
    81         scanf("%s", s);
    82         trans(ss, s);
    83         printf("%d\n", makeans(ss));
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    【机器学习】浅谈协方差
    python {}.format
    【机器学习】准确率、精确率、召回率
    【声纹识别】 EER
    【机器学习】 最形象的入门
    逻辑卷-LVM
    RAID及软RAID的实现
    输入数字or 字符串,统计重复次数---字典统计练习
    Python-数据结构之dict(字典*****)
    POJ 3204 网络流的必须边
  • 原文地址:https://www.cnblogs.com/swm8023/p/2711782.html
Copyright © 2011-2022 走看看