1. 程式人生 > >Censored! POJ - 1625

Censored! POJ - 1625

sigma lan void d+ get str ont con pen

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

拖了倆月的題目終於解決了...

Censored! POJ - 1625