码迷,mamicode.com
首页 > 其他好文 > 详细

Passwords Gym - 101174E

时间:2017-10-12 19:05:17      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:lan   tar   sig   nod   one   技术分享   分享   log   opened   

Passwords

 Gym - 101174E 

ac自动机 + DP

 

技术分享
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int sigma = 26;
  4 const int maxnode = 1010;
  5 const int mod = 1000003;
  6 int dp[21][maxnode][8];
  7 struct AC{
  8     int ch[maxnode][sigma];
  9     int f[maxnode];
 10     int mc[maxnode];
 11     int sz;
 12     int yy[11];
 13 
 14     void init(){
 15         memset(ch[0], 0, sizeof(ch[0]));
 16         memset(mc, 0, sizeof(mc));
 17         memset(yy, -1, sizeof(yy));
 18         sz = 1;
 19         yy[0] = o - a;
 20         yy[1] = i - a;
 21         yy[3] = e - a;
 22         yy[5] = s - a;
 23         yy[7] = t - a;
 24     }
 25 
 26     int idx(char c) {
 27         return c-a;
 28     }
 29 
 30     void insert(char *s) {
 31         int n = strlen(s), u = 0;
 32         for(int i = 0; i < n; i++){
 33             int c = idx(s[i]);
 34             if(!ch[u][c]){
 35                 memset(ch[sz], 0, sizeof(ch[sz]));
 36                 ch[u][c] = sz++;
 37             }
 38             u = ch[u][c];
 39         }
 40         mc[u] = 1;
 41     }
 42 
 43     void getfail(){
 44         queue<int> q;
 45         f[0] = 0;
 46         for(int c = 0; c < sigma; c++){
 47             int u = ch[0][c];
 48             if(u) {
 49                 q.push(u);
 50                 f[u] = 0;
 51             }
 52         }
 53         while(!q.empty()){
 54             int r = q.front();
 55             q.pop();
 56             for(int c = 0; c < sigma; c++){
 57                 int u = ch[r][c];
 58                 if(!u){
 59                     ch[r][c] = ch[f[r]][c];
 60                     continue;
 61                 }
 62                 q.push(u);
 63                 int v = f[r];
 64                 while(v && !ch[v][c]) v = f[v];
 65                 f[u] = ch[v][c];
 66                 mc[u] |= mc[f[u]];
 67             }
 68         }
 69     }
 70 }ac;
 71 
 72 void add(int &a, int b){
 73     a = a+b;
 74     if(a < 0)  a += mod;
 75     if(a >= mod) a -= mod;
 76 }
 77 
 78 void solve(int a, int b) {
 79     memset(dp, 0, sizeof(dp));
 80     dp[0][0][0] = 1;
 81     for(int i = 1; i <= b; i++){
 82         for(int j = 0; j < ac.sz; j++){
 83             if(ac.mc[j]) continue;
 84             for(int k = 0; k < 8; k++){
 85                // if(dp[i-1][j][k]==0) continue;
 86                 for(int c = 0; c < sigma; c++){
 87                     int u = ac.ch[j][c];
 88                     if(ac.mc[u]) continue;
 89                     add(dp[i][u][k|(1<<0)], dp[i-1][j][k]);
 90                     add(dp[i][u][k|(1<<1)], dp[i-1][j][k]);
 91                 }
 92                 for(int c = 0; c < 10; c++){
 93                     if(ac.yy[c] == -1){
 94                         add(dp[i][0][k|(1<<2)], dp[i-1][j][k]);
 95                     } else {
 96                         int u = ac.ch[j][ac.yy[c]];
 97                         if(ac.mc[u]) continue;
 98                         add(dp[i][u][k|(1<<2)], dp[i-1][j][k]);
 99                     }
100                 }
101             }
102         }
103     }
104     int ans = 0;
105     for(int i = a; i <= b; i++){
106         for(int j = 0; j < ac.sz; j++){
107             add(ans, dp[i][j][7]);
108         }
109     }
110     printf("%d\n", ans);
111 }
112 
113 int main(){
114     int a, b, n;
115    // freopen("in.txt", "r", stdin);
116     scanf("%d %d %d", &a, &b, &n);
117     ac.init();
118     char s[21];
119     for(int i = 0; i < n; i++){
120         scanf("%s", s);
121         ac.insert(s);
122     }
123     ac.getfail();
124     solve(a, b);
125     return 0;
126 }
View Code

 

Passwords Gym - 101174E

标签:lan   tar   sig   nod   one   技术分享   分享   log   opened   

原文地址:http://www.cnblogs.com/yijiull/p/7657346.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!