zoukankan      html  css  js  c++  java
  • zoj3228Searching the String(ac自动机)

    链接

    这个题把病毒分为了两种,一种包含可以覆盖,另一种不可以,需要分别求出包含他们的个数,可以把两种都建在一颗tire树上,在最后求得时候判断一下当前节点是属于哪种字符串,如果是不包含的需要判断一下pre[i]+len[i]<=当前位置。

    注意会有重复字符串,可以先map处理一下。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<string>
     11 #include<map>
     12 using namespace std;
     13 #define N 600110
     14 #define LL long long
     15 #define INF 0xfffffff
     16 const double eps = 1e-8;
     17 const double pi = acos(-1.0);
     18 const double inf = ~0u>>2;
     19 const int child_num = 26;
     20 char vir[10];
     21 char s[N/6];
     22 int o[N/6],len[N/6],ans[N/6][2],po[N/6];
     23 int cc[N/6];
     24 map<string,int>f;
     25 vector<int>ed[N/6];
     26 class AC
     27 {
     28     private:
     29     int ch[N][child_num];
     30     int fail[N];
     31     int Q[N];
     32     int val[N];
     33     int sz;
     34     int id[128];
     35     public:
     36     void init()
     37     {
     38         fail[0] = 0;
     39         for(int i = 0 ;i < child_num ; i++)
     40         id[i+'a'] = i;
     41     }
     42     void reset()
     43     {
     44         memset(ch[0],0,sizeof(ch[0]));
     45         memset(val,0,sizeof(val));
     46         sz = 1;
     47     }
     48     void insert(char *a,int key)
     49     {
     50         int p = 0;
     51         for(; *a ; a++)
     52         {
     53             int d= id[*a];
     54             if(ch[p][d]==0)
     55             {
     56                 memset(ch[sz],0,sizeof(ch[sz]));
     57                 ch[p][d] = sz++;
     58             }
     59             p = ch[p][d];
     60         }
     61         val[p] = key;
     62     }
     63     void construct()
     64     {
     65         int i,head=0,tail = 0;
     66         for(i = 0; i  < child_num ;i++)
     67         {
     68             if(ch[0][i])
     69             {
     70                 fail[ch[0][i]] = 0;
     71                 Q[tail++] = ch[0][i];
     72             }
     73         }
     74         while(head!=tail)
     75         {
     76             int u = Q[head++];
     77             for(i = 0; i < child_num ; i++)
     78             {
     79                 if(ch[u][i])
     80                 {
     81                     fail[ch[u][i]] = ch[fail[u]][i];
     82                     Q[tail++] = ch[u][i];
     83                 }
     84                 else ch[u][i] = ch[fail[u]][i];
     85             }
     86         }
     87     }
     88     void work(int m,int kk,int g)
     89     {
     90         memset(ans,0,sizeof(ans));
     91         memset(po,-1,sizeof(po));
     92         int p = 0,i,k = strlen(s);
     93         for(i = 0 ; i < k ; i++)
     94         {
     95             int d = id[s[i]];
     96             p = ch[p][d];
     97             int tmp = p;
     98             while(tmp)
     99             {
    100                 int v = val[tmp];
    101                 ans[v][0]++;
    102                 if(po[v]+len[v]<=i)
    103                 {
    104                     po[v] = i;
    105                     ans[v][1]++;
    106                 }
    107                 tmp = fail[tmp];
    108             }
    109         }
    110         for(i = 1; i <= g ; i++)
    111         {
    112             for(int j = 0; j < ed[i].size() ; j++)
    113             {
    114                 int v = ed[i][j];
    115                 if(o[v]) cc[v] = ans[i][1];
    116                 else cc[v] = ans[i][0];
    117             }
    118         }
    119         printf("Case %d
    ",kk);
    120         for(i = 1 ; i <= m ;i++)
    121         printf("%d
    ",cc[i]);
    122         puts("");
    123     }
    124 }ac;
    125 int main()
    126 {
    127     int i,m,kk=0;
    128     ac.init();
    129     while(scanf("%s",s)!=EOF)
    130     {
    131         ac.reset();
    132         f.clear();
    133         scanf("%d",&m);
    134         int g = 0;
    135         for(i = 1 ; i <= m; i++)
    136         ed[i].clear();
    137         for(i = 1;i <= m ;i++)
    138         {
    139             scanf("%d%s",&o[i],vir);
    140             if(!f[vir])
    141             {
    142                 f[vir] = (++g);
    143                 ac.insert(vir,g);
    144                 len[g] = strlen(vir);
    145             }
    146             ed[f[vir]].push_back(i);
    147         }
    148         ac.construct();
    149         kk++;
    150         ac.work(m,kk,g);
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    田忌赛马 题解
    亚历山大的丢番图方程 题解
    zhx's contest题解
    芝麻OI比赛T7edges题解
    CSP-J2020游记
    Linux shell 学习笔记(五)
    Linux shell 学习笔记(四)
    Linux shell 学习笔记(三)
    Linux shell 学习笔记(二)
    Oracle并发
  • 原文地址:https://www.cnblogs.com/shangyu/p/3750784.html
Copyright © 2011-2022 走看看