HDU 5763

 

传送门

 

给你串A和串B,|B| <= |A|

已知串B有两种可能含义,求串A的总可能含义数

dp[i]表示串A的从头开始长度为i的串的可能意义的数目

若该长度为i的串的后缀与模式串B匹配,则该后缀可以选择替换或者不替换

dp[i] = dp[i - 1] + dp[i - Bl]   否则dp[i] = dp[i - 1]

 

 1 #include <queue>
 2 #include <vector>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 #define INF 0x3f3f3f3f
 8 #define MOD 1000000007
 9 using namespace std;
10 typedef long long LL;
11 typedef unsigned long long ULL;
12 const int maxn = 1e5 + 10;
13 char s1[maxn], s2[maxn];
14 int dp[maxn];
15 const ULL B = 100000007;
16 
17 void contain(char *a, char *b) {
18     int al = strlen(a), bl = strlen(b);
19     ULL t = 1;
20     for (int i = 0; i < al; i++) t *= B;
21     ULL ah = 0, bh = 0;
22     for (int i = 0; i < al; i++) ah = ah * B + a[i];
23     for (int i = 0; i < al; i++) bh = bh * B + b[i];
24     
25     memset(dp, 0, sizeof(dp));
26     for (int i = 0; i < al; i++) dp[i] = 1;
27     
28     for (int i = 0; i + al <= bl; i++) {
29         dp[i + al] = dp[i + al - 1];
30         if (ah == bh) {
31             dp[i + al] = (dp[i + al] + dp[i]) % MOD;
32         }
33         if (i + al < bl) bh = bh * B + b[i + al] - b[i] * t;
34     }
35 }
36 
37 
38 int main(int argc, const char * argv[]) {
39     int T;
40     scanf("%d", &T);
41     for (int t = 1; t <= T; t++) {
42         scanf("%s%s", s1, s2);
43         contain(s2, s1);
44         int l1 = strlen(s1);
45         printf("Case #%d: ", t);
46         printf("%d\n", dp[l1]);
47         
48     }
49     return 0;
50 }

 

posted @ 2017-08-03 15:46  xFANx  阅读(104)  评论(0编辑  收藏  举报