• HDU 6208 The Dominator of Strings ——(青岛网络赛,AC自动机)


      最长的才可能成为答案,那么除了最长的以外全部insert到自动机里,再拿最长的去match,如果match完以后cnt全被清空了,那么这个最长串就是答案。事实上方便起见这个最长串一起丢进去也无妨,而且更好写(时间也没有慢特别多)。

      另外需要注意的一点是init()里头的memset只需要清空之前用过的节点而不是所有节点,这是经常被卡的一点。

      代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <queue>
      5 #include <vector>
      6 using namespace std;
      7 const int MAX_N = 100000 + 50;
      8 const int MAX_Tot = 100000 + 50;
      9 
     10 struct Aho
     11 {
     12     struct state
     13     {
     14         int nxt[26];
     15         int fail,cnt;
     16     }stateTable[MAX_Tot];
     17 
     18     int size;
     19 
     20     queue<int> que;
     21 
     22     void init()
     23     {
     24         while(que.size()) que.pop();
     25         for(int i=0;i<size;i++)
     26         {
     27             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
     28             stateTable[i].fail = stateTable[i].cnt = 0;
     29         }
     30         size = 1;
     31     }
     32 
     33     void insert(char *s)
     34     {
     35         int n = strlen(s);
     36         int now = 0;
     37         for(int i=0;i<n;i++)
     38         {
     39             char c = s[i];
     40             if(!stateTable[now].nxt[c-'a'])
     41                 stateTable[now].nxt[c-'a'] = size++;
     42             now = stateTable[now].nxt[c-'a'];
     43         }
     44         stateTable[now].cnt++;
     45     }
     46 
     47     void build()
     48     {
     49         stateTable[0].fail = -1;
     50         que.push(0);
     51 
     52         while(que.size())
     53         {
     54             int u = que.front();que.pop();
     55             for(int i=0;i<26;i++)
     56             {
     57                 if(stateTable[u].nxt[i])
     58                 {
     59                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
     60                     else
     61                     {
     62                         int v = stateTable[u].fail;
     63                         while(v != -1)
     64                         {
     65                             if(stateTable[v].nxt[i])
     66                             {
     67                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
     68                                 break;
     69                             }
     70                             v = stateTable[v].fail;
     71                         }
     72                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
     73                     }
     74                     que.push(stateTable[u].nxt[i]);
     75                 }
     76             }
     77         }
     78     }
     79 
     80     //bool mark[MAX_Tot];
     81     void Get(int u)
     82     {
     83         while(u)
     84         {
     85             if(stateTable[u].cnt == -1) break;
     86             stateTable[u].cnt = -1;
     87             u = stateTable[u].fail;
     88         }
     89     }
     90 
     91     int match(char *s)
     92     {
     93         //memset(mark, 0, sizeof mark);
     94         int n = strlen(s);
     95         int res = 0, now = 0;
     96         for(int i=0;i<n;i++)
     97         {
     98             char c = s[i];
     99             if(stateTable[now].nxt[c-'a']) now = stateTable[now].nxt[c-'a'];
    100             else
    101             {
    102                 int p = stateTable[now].fail;
    103                 while(p != -1 && stateTable[p].nxt[c-'a'] == 0) p = stateTable[p].fail;
    104                 if(p == -1) now = 0;
    105                 else now = stateTable[p].nxt[c-'a'];
    106             }
    107 
    108             Get(now);
    109         }
    110         for(int i=1;i<size;i++) if(stateTable[i].cnt > 0) return 0;
    111         return 1;
    112     }
    113 }aho;
    114 
    115 int T,n;
    116 char s[MAX_N], t[MAX_N];
    117 
    118 int main()
    119 {
    120     int T;scanf("%d",&T);
    121     while(T--)
    122     {
    123         vector<char> v;
    124         aho.init();
    125         scanf("%d",&n);
    126         int maxn = 0;
    127         for(int i=1;i<=n;i++)
    128         {
    129             scanf("%s",s);
    130             //aho.insert(s);
    131             int sz = strlen(s);
    132             for(int j=0;j<sz;j++) v.push_back(s[j]);
    133             v.push_back('#');
    134             if(sz > maxn)
    135             {
    136                 maxn = sz;
    137                 strcpy(t, s);
    138             }
    139         }
    140         int tot = 0;
    141         for(int i=0;i<v.size();i++)
    142         {
    143             if(v[i] == '#')
    144             {
    145                 s[tot++] = 0;
    146                 tot = 0;
    147                 if(strcmp(s, t)) aho.insert(s);
    148             }
    149             else s[tot++] = v[i];
    150         }
    151         aho.build();
    152         int ans = aho.match(t);
    153         if(ans) puts(t);
    154         else puts("No");
    155     }
    156 }
  • 相关阅读:
    CSS中文API
    廖雪峰Git教程
    数据操作的几个名词即model、dal、dao、orm和ar 解释
    Jetty
    Git介绍与使用
    c3p0、dbcp、druid三大连接池对比
    (转)JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)
    08 bash特性--shell脚本编程入门
    07 grep命令与正则表达式
    06 I/O重定向与管道符
  • 原文地址:https://www.cnblogs.com/zzyDS/p/7570065.html
Copyright © 2020-2023  润新知