fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int MOD = 1337377;
  12. const int N = 4e3 + 5;
  13. const int M = 3e5 + 5;
  14. const int MX = 4e5 + 5;
  15.  
  16. void add(int& a, int b) {
  17. a += b;
  18. if (a >= MOD) a -= MOD;
  19. }
  20.  
  21. struct Node {
  22. int nxt[26];
  23. bool mark = false;
  24.  
  25. Node() {
  26. memset(nxt, -1, sizeof nxt);
  27. }
  28. };
  29.  
  30. int sz;
  31. Node trie[MX];
  32.  
  33. void addString(const string& s) {
  34. int v = 0;
  35. for (char ch : s) {
  36. int c = ch - 'a';
  37. if (trie[v].nxt[c] == -1) {
  38. trie[v].nxt[c] = ++sz;
  39. }
  40. v = trie[v].nxt[c];
  41. }
  42. trie[v].mark = true;
  43. }
  44.  
  45. int n, m;
  46. string s;
  47. string t[N];
  48.  
  49. int dp[M]; // dp[i] = Số cách tách đoạn [1, i]
  50.  
  51. int main() {
  52. ios::sync_with_stdio(false);
  53. cin.tie(nullptr);
  54. cin >> s;
  55. m = s.size();
  56. s = ' ' + s;
  57.  
  58. cin >> n;
  59. for (int i = 1; i <= n; i++) {
  60. cin >> t[i];
  61. addString(t[i]);
  62. }
  63.  
  64. dp[0] = 1;
  65. for (int i = 0; i < m; i++) {
  66. int v = 0;
  67. for (int j = i + 1; j <= m; j++) { // O(100)
  68. int c = s[j] - 'a';
  69. if (trie[v].nxt[c] == -1) break;
  70. v = trie[v].nxt[c];
  71. if (trie[v].mark) add(dp[j], dp[i]); // đoạn [i + 1, j] phải là một từ thuộc tập từ đã cho
  72. }
  73. }
  74.  
  75. cout << dp[m] << '\n';
  76. }
Success #stdin #stdout 0.01s 46480KB
stdin
abcd
4
a
b
cd
ab
stdout
2