zoj3430Detect the Virus(ac自动机)

链接

解码之后是跟普通的自动机求解一下的,只不过解码比较恶心,512=》N》=0 ,所以不能用字符串来存,需要转换成整数来做。

  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 using namespace std;

 11 #define N 53769

 12 #define NN 15010

 13 #define LL long long

 14 #define INF 0xfffffff

 15 const double eps = 1e-8;

 16 const double pi = acos(-1.0);

 17 const double inf = ~0u>>2;

 18 const int child_num = 258;

 19 char s[NN],vir[NN];

 20 int di[NN*8],od[NN],vv[NN];

 21 bool f[N];

 22 class ACAutomation

 23 {

 24     private:

 25     int ch[N][child_num];

 26     int val[N];

 27     int fail[N];

 28     int Q[N];

 29     int id[258];

 30     int sz;

 31    // int dp[2][N][1<<10];

 32     public:

 33     void init()

 34     {

 35         fail[0] = 0;

 36         for(int i = 0 ; i < child_num;  i++)

 37         id[i] = i;

 38     }

 39     void reset()//初始化

 40     {

 41         memset(ch[0],0,sizeof(ch[0]));

 42         memset(val,0,sizeof(val));

 43         sz = 1;

 44     }

 45     void insert(int *a,int key,int k)//建立trie树

 46     {

 47         int p = 0;

 48         for( int i = 0; i < k ; i++)

 49         {

 50             int c = id[a[i]];

 51             if(ch[p][c]==0)

 52             {

 53                 memset(ch[sz],0,sizeof(ch[sz]));

 54                 ch[p][c] = sz++;

 55             }

 56             p = ch[p][c];

 57         }

 58         val[p] += key;

 59     }

 60     void construct()//构建fail指针

 61     {

 62         int head = 0,tail = 0,i;

 63         for(i = 0 ;i < child_num ; i++)

 64         {

 65             if(ch[0][i])

 66             {

 67                 fail[ch[0][i]] = 0;

 68                 Q[tail++] = ch[0][i];

 69             }

 70         }

 71         while(head!=tail)

 72         {

 73             int u = Q[head++];

 74             for(i = 0 ;i < child_num ;i ++)

 75             {

 76                 if(ch[u][i]!=0)

 77                 {

 78                     Q[tail++] = ch[u][i];

 79                     fail[ch[u][i]] = ch[fail[u]][i];

 80                 }

 81                 else

 82                 ch[u][i] = ch[fail[u]][i];

 83             }

 84         }

 85     }

 86     int work(int *s,int k)

 87     {

 88         int p = 0,ans = 0;

 89         memset(f,0,sizeof(f));

 90         for(int i = 0; i < k ; i++)

 91         {

 92             int d = id[s[i]];

 93             p = ch[p][d];

 94             int tmp = p;

 95             while(tmp!=0&&!f[tmp])

 96             {

 97                 ans+=val[tmp];

 98                 f[tmp] = 1;

 99                 tmp = fail[tmp];

100             }

101         }

102         return ans;

103     }

104 }ac;

105 int change(char *a)

106 {

107     int i,k = strlen(a),j;

108     int g = 0,gg,num =0 ;

109     for(i = 0;i < k ; i++)

110     {

111         if(a[i]=='=')

112         {

113             num++;

114             continue;

115         }

116         int x = od[a[i]];gg=0;

117         for(j=5;j>=0;j--)

118         {

119             di[g++]=((x&(1<<j))>0);

120         }

121     }

122     if(num==1)

123     g-=2;

124     else if(num==2)

125     g-=4;

126     gg = 0;

127     int y = 0;

128     for(j = 0 ;j < g ; j++)

129     {

130         y+=di[j]*(1<<(7-j%8));

131         if((j+1)%8==0)

132         {

133             vv[gg++] = y;

134             y = 0;

135         }

136     }

137     return g/8;

138 }

139 int main()

140 {

141     int n,i,m;

142     for(i = 'A' ; i <= 'Z' ; i++)

143     od[i] = i-'A';

144     for(i = 'a' ; i <= 'z' ; i++)

145     od[i] = 26+i-'a';

146     for(i = '0'; i <= '9' ; i++)

147     od[i] = 52+i-'0';

148     od['+'] = 62,od['/'] = 63;

149     ac.init();

150     while(scanf("%d",&n)!=EOF)

151     {

152         ac.reset();

153         for(i = 1; i <= n; i++)

154         {

155             scanf("%s",vir);

156             int len = change(vir);

157             ac.insert(vv,1,len);

158         }

159         ac.construct();

160         scanf("%d",&m);

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

162         {

163             scanf("%s",s);

164             int len = change(s);

165             printf("%d\n",ac.work(vv,len));

166         }

167         puts("");

168     }

169     return 0;

170 }
View Code

 

你可能感兴趣的:(AC自动机)