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\n",kk);

120         for(i = 1 ; i <= m ;i++)

121         printf("%d\n",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

 

你可能感兴趣的:(String)