Censored! POJ - 1625

Censored!

 POJ - 1625 

ac自动机 + 高精度 + dp

 

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

 

拖了俩月的题目终于解决了...

转载于:https://www.cnblogs.com/yijiull/p/7654407.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值