hdu 4758
题意:求长度为n+m,有n个0,且必须包含串s1和s2的串的个数,s1和s2可以重叠;
太久没写AC了,导致比赛的时候很裸的AC自动机的题目都没有往那边想,唉~
比赛的时候就想到状态dp[i][4],但是发现在某一时候在末尾加入s1后会把s2也引入,就是状态转移想不清楚;然后就没有然后了;
AC自动机,通过建AC自动机,得出在任何一个状态下s1,s2出现的情况记录在val[]里,这样用dp[len][i][n][state]状态(表示长度为len的串,最后一个字符在AC自动机里的结点I位,0的个数为n,s1,s2的出现情况的个数)就可以DP了;
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<vector> 5 #include<cmath> 6 #include<algorithm> 7 #include<iostream> 8 #include<queue> 9 using namespace std; 10 typedef long long LL; 11 const int maxnode = 200+10; 12 const int sigma_sz = 2; 13 const int N = 210; 14 const int Mod = 1000000007; 15 int dp[2][maxnode][110][4]; 16 int n,m; 17 struct AC{ 18 int ch[maxnode][sigma_sz]; 19 int f[maxnode],val[maxnode]; 20 int sz; 21 queue<int> q; 22 void init(){ 23 sz = 1; 24 memset(ch[0],0,sizeof(ch[0])); 25 memset(val,0,sizeof(val)); 26 } 27 int idx(char c) { 28 if (c == 'R') return 0; 29 return 1; 30 } 31 void insert(char *s,int id) { 32 int len = strlen(s), u = 0; 33 for (int i = 0; i < len; i++) { 34 int c = idx(s[i]); 35 if (ch[u][c] == 0) { 36 memset(ch[sz],0,sizeof(ch[sz])); 37 ch[u][c] = sz++; 38 } 39 u = ch[u][c]; 40 } 41 val[u] = id; 42 } 43 void getFail(){ 44 while (!q.empty()) q.pop(); 45 for (int i = 0; i < sigma_sz; i++) { 46 int c = ch[0][i]; 47 if (c) { 48 f[c] = 0; q.push(c); 49 } 50 } 51 while (!q.empty()) { 52 int u = q.front(); q.pop(); 53 for (int i = 0; i < sigma_sz; i++) { 54 int v = ch[u][i]; 55 if (v) { 56 q.push(v); 57 int r = f[u]; 58 while (r && ch[r][i] == 0) r = f[r]; 59 f[v] = ch[r][i]; 60 val[v] |= val[f[v]]; 61 }else { 62 ch[u][i] = ch[f[u]][i]; 63 } 64 } 65 } 66 } 67 void solve(){ 68 getFail(); 69 int pos = 0; 70 dp[pos][0][0][0] = 1; 71 for (int i = 0 ; i < n+m; i++) { 72 for (int j = 0; j < sz; j++){ 73 for (int x = 0; x <= i; x++) { 74 for (int y = 0; y <= 3; y++) { 75 for (int k = 0; k < sigma_sz; k++) { 76 int c = ch[j][k]; 77 int f = (k == 0 ? 1 : 0); 78 dp[pos^1][c][x+f][y|val[c]] += dp[pos][j][x][y]; 79 dp[pos^1][c][x+f][y|val[c]] %= Mod; 80 } 81 } 82 } 83 } 84 memset(dp[pos],0,sizeof(dp[pos])); 85 pos ^= 1; 86 } 87 LL ret = 0; 88 for (int i = 0; i < sz; i++) { 89 ret = (ret + dp[pos][i][n][3]) % Mod; 90 } 91 printf("%lld ",ret); 92 } 93 94 }H; 95 char s[110]; 96 void solve(){ 97 memset(dp,0,sizeof(dp)); 98 H.solve(); 99 } 100 int main(){ 101 int T; scanf("%d",&T); 102 while (T--) { 103 scanf("%d%d",&n,&m); 104 H.init(); 105 for (int i = 0; i < 2; i++) { 106 scanf("%s",s); 107 H.insert(s,1<<i); 108 } 109 solve(); 110 } 111 return 0; 112 }
UVALive 3942
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<vector> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int N = 300000+10; 10 const int maxnode = 400000+10; 11 const int sigma_sz = 26; 12 const int Mod = 20071027; 13 int dp[N]; 14 struct AC{ 15 int ch[maxnode][sigma_sz]; 16 int sz; 17 queue<int> q; 18 int val[maxnode], le[maxnode], last[maxnode], f[maxnode];//le[] > 0 is ends 19 void init(){ 20 sz = 1; 21 memset(val,0,sizeof(val)); 22 memset(le,0,sizeof(le)); 23 memset(ch[0],0,sizeof(ch[0])); 24 } 25 int idx(char c) { 26 return c - 'a'; 27 } 28 void insert(char *s) { 29 int len = strlen(s), u = 0; 30 for (int i = 0; i < len; i++) { 31 int v = idx(s[i]); 32 if (ch[u][v] == 0) { 33 memset(ch[sz],0,sizeof(ch[sz])); 34 ch[u][v] = sz++; 35 } 36 u = ch[u][v]; 37 } 38 val[u] = 1; 39 le[u] = len; 40 } 41 void getFail() { 42 while (!q.empty()) q.pop(); 43 for (int i = 0; i < sigma_sz; i++) { 44 int v = ch[0][i]; 45 if (v) { 46 q.push(v); f[v] = 0; last[v] = 0; 47 } 48 } 49 while (!q.empty()) { 50 int u = q.front(); q.pop(); 51 for (int i = 0; i < sigma_sz; i++) { 52 int v = ch[u][i]; 53 if (v) { 54 q.push(v); 55 int r = f[u]; 56 while (r && ch[r][i] == 0) r = f[r]; 57 f[v] = ch[r][i]; 58 val[v] |= val[f[v]]; 59 last[v] = le[f[v]] ? f[v] : last[f[v]]; 60 }else { 61 ch[u][i] = ch[f[u]][i]; 62 } 63 } 64 } 65 } 66 void solve(char *T){ 67 int len = strlen(T); 68 int u = 0; 69 for (int i = 1; i < len; i++) { 70 int c = idx(T[i]); 71 int r = ch[u][c]; 72 if (val[r]) { 73 int j = r; 74 while (j) { 75 if (le[j]) dp[i] = (dp[i] + dp[i - le[j]] ) % Mod; 76 j = last[j]; 77 } 78 79 } 80 u = ch[u][c]; 81 } 82 } 83 }H; 84 int n; 85 char text[N],p[N]; 86 void solve(){ 87 memset(dp,0,sizeof(dp)); 88 dp[0] = 1; 89 H.solve(text); 90 printf("%d ",dp[strlen(text)-1]); 91 } 92 int main(){ 93 int cas = 0; 94 text[0] = '#'; 95 while (~scanf("%s",text+1)) { 96 scanf("%d",&n); 97 H.init(); 98 for (int i = 0; i < n; i++) { 99 scanf("%s",p); 100 H.insert(p); 101 } 102 H.getFail(); 103 printf("Case %d: ",++cas); 104 solve(); 105 } 106 return 0; 107 } 108 /* 109 abcd 110 4 111 a 112 b 113 cd 114 ab 115 heshehishers 116 7 117 s 118 h 119 e 120 he 121 she 122 his 123 hers 124 125 */
UALive 4670
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<vector> 5 #include<algorithm> 6 #include<iostream> 7 #include<queue> 8 using namespace std; 9 const int maxnode = 15000+10; 10 const int sigma_sz = 26; 11 const int N = 1000000+10; 12 int cnt[N]; 13 struct AC{ 14 int ch[maxnode][sigma_sz]; 15 int f[maxnode],val[maxnode],isend[maxnode],last[maxnode]; 16 int sz; 17 queue<int> q; 18 void init(){ 19 sz = 1; 20 memset(val,0,sizeof(val)); 21 memset(isend,0,sizeof(isend)); 22 memset(ch[0],0,sizeof(ch[0])); 23 } 24 int idx(char c) { 25 return c - 'a'; 26 } 27 void insert(char *s,int id){ 28 int len = strlen(s), u = 0; 29 for (int i = 0; i < len; i++) { 30 int c = idx(s[i]); 31 if (ch[u][c] == 0) { 32 memset(ch[sz],0,sizeof(ch[sz])); 33 ch[u][c] = sz++; 34 } 35 u = ch[u][c]; 36 } 37 val[u] = 1; isend[u] = id; 38 } 39 void getFail(){ 40 while (!q.empty()) q.pop(); 41 for (int i = 0; i < sigma_sz; i++) { 42 int c = ch[0][i]; 43 if (c) { 44 f[c] = 0; last[c] = 0; q.push(c); 45 } 46 } 47 while (!q.empty()) { 48 int u = q.front(); q.pop(); 49 for (int i = 0; i < sigma_sz; i++) { 50 int v = ch[u][i]; 51 if (v) { 52 q.push(v); 53 int r = f[u]; 54 while (r && ch[r][i] == 0) r = f[r]; 55 f[v] = ch[r][i]; 56 val[v] |= val[f[v]]; 57 last[v] = isend[f[v]] ? f[v] : last[f[v]]; 58 }else { 59 ch[u][i] = ch[f[u]][i]; 60 } 61 } 62 } 63 } 64 void solve(char *T){ 65 getFail(); 66 int len = strlen(T), u = 0; 67 for (int i = 0; i < len; i++) { 68 int c = idx(T[i]); 69 u = ch[u][c]; 70 int j = u; 71 if (val[j]) { 72 while (j) { 73 if (isend[j]) cnt[isend[j]]++; 74 j = last[j]; 75 } 76 } 77 } 78 } 79 }H; 80 int n; 81 char text[N],p[200][80]; 82 void solve(){ 83 H.solve(text); 84 85 int mx = 0; 86 for (int i = 1; i <= n; i++) { 87 if (cnt[i] > mx) mx = cnt[i]; 88 } 89 printf("%d ",mx); 90 for (int i = 1 ; i <= n; i++) { 91 if (cnt[i] == mx) printf("%s ",p[i]); 92 } 93 94 } 95 int main(){ 96 while (~scanf("%d",&n),n) { 97 memset(cnt,0,sizeof(cnt)); 98 H.init(); 99 for (int i = 1 ; i <= n; i++) { 100 scanf("%s",p[i]); 101 // cout<<p[i]<<endl; 102 H.insert(p[i],i); 103 } 104 scanf("%s",text); 105 solve(); 106 } 107 return 0; 108 }