本文共 1576 字,大约阅读时间需要 5 分钟。
设\(f[i][j]\)表示前\(i\)个串匹配到位置\(j\)的方案数,匹配一下第\(i\)个串进行转移即可
本来写了\(hash\),发现没过,又写了一个\(KMP\),依旧\(WA\),无奈去翻题解,竟然要取模??!!
#include #include #include #include #include #include #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)#define REP(i,n) for (int i = 1; i <= (n); i++)#define mp(a,b) make_pair (a,b)#define cls(s) memset(s,0,sizeof(s))#define cp pair #define LL long long intusing namespace std;const int maxn = 10005,maxm = 100005,INF = 1000000000,Mod = 1000000007;inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag;}char s[maxn],P[maxn];int len,K,m,nxt[maxn];LL f[105][maxn];void getf(){ nxt[1] = 0; for (int i = 1,j = 0; i < m; i++){ while (j && P[i + 1] != P[j + 1]) j = nxt[j]; if (P[i + 1] == P[j + 1]) nxt[i + 1] = ++j; }}int main(){ K = read(); scanf("%s",s + 1); len = strlen(s + 1); for (int i = 0; i <= len; i++) f[0][i] = 1; for (int i = 1; i <= K; i++){ int a = read(); while (a--){ scanf("%s",P + 1); m = strlen(P + 1); getf(); int j = 0; for (int k = 1; k <= len; k++){ while (j && P[j + 1] != s[k]) j = nxt[j]; if (P[j + 1] == s[k]) j++; if (j == m){ f[i][k] = (f[i][k] + f[i - 1][k - m]) % Mod; } } } } LL ans = 0; for (int i = 0; i <= len; i++) ans = (ans + f[K][i]) % Mod; printf("%lld\n",ans); return 0;}
转载于:https://www.cnblogs.com/Mychael/p/9051286.html