fork download
  1. #include <bits/stdc++.h>
  2.  
  3. #define ll long long
  4. #define el cout << '\n'
  5. #define ii pair<int, int>
  6. #define fi first
  7. #define se second
  8.  
  9. using namespace std;
  10.  
  11. struct HASH
  12. {
  13. int n, BASE, MOD;
  14. string s;
  15. vector<ll> h, p;
  16.  
  17. HASH(int n = 0, int BASE = 0, int MOD = 0, string s = "") :
  18. n(n), BASE(BASE), MOD(MOD), s(s)
  19. {
  20. h.assign(n + 5, 0);
  21. p.assign(n + 5, 0);
  22. p[0] = 1;
  23. for (int i = 1; i <= n; i++)
  24. {
  25. h[i] = (h[i - 1] * BASE + s[i]) % MOD;
  26. p[i] = BASE * p[i - 1] % MOD;
  27. }
  28. }
  29. ll get_hash(int l, int r)
  30. {
  31. ll a = h[r] - h[l - 1] * p[r - l + 1] % MOD;
  32. a %= MOD;
  33. a += MOD;
  34. return a % MOD;
  35. }
  36. };
  37. struct Fenwick_Tree
  38. {
  39. int maxn;
  40. vector<ii> bit;
  41.  
  42. Fenwick_Tree(int n = 0) : maxn(n)
  43. {
  44. bit.assign(n + 5, {0, 0});
  45. }
  46. void update(int x, ii v)
  47. {
  48. for (;x <= maxn; x += x &- x)
  49. bit[x] = {bit[x].fi + v.fi, bit[x].se + v.se};
  50. }
  51. ii get(int x)
  52. {
  53. ii ans = {0, 0};
  54. for (; x; x &= x - 1)
  55. ans = {ans.fi + bit[x].fi, ans.se + bit[x].se};
  56. return ans;
  57. }
  58. };
  59.  
  60. const int maxn = 2e5;
  61. const int MOD = 998244353;
  62. const int BASE = 256;
  63.  
  64. int n, m;
  65. ll ans = 0, sum_y = 0;
  66. string s_1, s_2, fin;
  67. HASH h_1, h_2, h_t;
  68. vector<ii> a, b;
  69. vector<ll> v;
  70. Fenwick_Tree tree;
  71.  
  72. int bs_prefix(int l, int r)
  73. {
  74. int pivot = l;
  75. int ans = 0;
  76. while (l <= r)
  77. {
  78. int m = l + r >> 1;
  79. ll x = h_1.get_hash(pivot, m);
  80. ll y = h_t.get_hash(1, m - pivot + 1);
  81. // cout << pivot << ' ' << m << ' ' << m - pivot + 1 << ' ' << x << ' ' << y, el;
  82. if (x == y)
  83. {
  84. ans = m;
  85. l = m + 1;
  86. }
  87. else
  88. r = m - 1;
  89. }
  90. return ans;
  91. }
  92. int bs_suffix(int l, int r)
  93. {
  94. int pivot = r;
  95. int ans = 0;
  96. while (l <= r)
  97. {
  98. int mid = l + r >> 1;
  99. ll x = h_2.get_hash(mid, pivot);
  100. ll y = h_t.get_hash(m - (pivot - mid + 1) + 1, m);
  101. // cout << mid << ' ' << pivot << ' ' << m - (pivot - mid + 1) + 1 << ' ' << m << ' ' << x << ' ' << y, el;
  102. if (x == y)
  103. {
  104. ans = mid ;
  105. r = mid - 1;
  106. }
  107. else
  108. l = mid + 1;
  109. }
  110. return ans;
  111. }
  112. bool cmp(ii a, ii b)
  113. {
  114. return a.se - a.fi < b.se - b.fi;
  115. }
  116. bool cmp_2(ii a, ii b)
  117. {
  118. return a.se < b.se || (a.se == b.se && a.fi < b.fi);
  119. }
  120. int get_id(ll x)
  121. {
  122. return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
  123. }
  124.  
  125. int main()
  126. {
  127. ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  128. if (fopen("OBSTACLE.INP", "r"))
  129. {
  130. freopen("OBSTACLE.INP", "r", stdin);
  131. freopen("OBSTACLE.OUT", "w", stdout);
  132. }
  133.  
  134. cin >> n >> m;
  135. cin >> s_1;
  136. cin >> s_2;
  137. cin >> fin;
  138.  
  139. h_1 = HASH(n, BASE, MOD, " " + s_1);
  140. h_2 = HASH(n, BASE, MOD, " " + s_2);
  141. h_t = HASH(m, BASE, MOD, " " + fin);
  142.  
  143. for (int i = 1; i <= n; i++)
  144. {
  145. int x = bs_prefix(i, min(n, i + m - 1));
  146. int y = bs_suffix(max(1, i - m + 1), i);
  147. if (x)
  148. a.push_back({i, x});
  149. if (y)
  150. b.push_back({y, i});
  151. }
  152. sort(a.begin(), a.end(), cmp);
  153. sort(b.begin(), b.end(), cmp);
  154. for (int i = 0, j = 0; i < a.size(); i++)
  155. {
  156. while (j < b.size() && a[i].se - a[i].fi - m >= b[j].fi - b[j].se - 2)
  157. {
  158. sum_y += min(0, b[j].se - b[j].fi + 2 - m);
  159. j++;
  160. }
  161. ans += (a[i].se - a[i].fi + 1) * j + sum_y;
  162. }
  163. sort(a.begin(), a.end());
  164. sort(b.begin(), b.end(), cmp_2);
  165. for (ii pr : a)
  166. v.push_back(pr.se - pr.fi - m);
  167. for (ii pr : b)
  168. v.push_back(pr.fi - pr.se - 2);
  169. sort(v.begin(), v.end());
  170. // for (ii pr : a)
  171. // cout << pr.fi << ' ' << pr.se, el;
  172. // for (ii pr : b)
  173. // cout << pr.fi << ' ' << pr.se, el;
  174. tree = Fenwick_Tree(v.size() + 5);
  175. for (int i = a.size() - 1, j = b.size() - 1; i >= 0; i--)
  176. {
  177. while (j >= 0 && a[i].fi < b[j].se + 2 - m)
  178. {
  179. tree.update(get_id(b[j].fi - b[j].se - 2), {1, min(0, b[j].se - b[j].fi + 2 - m)});
  180. j--;
  181. }
  182. ii x = tree.get(get_id(a[i].se - a[i].fi - m));
  183. ans -= (a[i].se - a[i].fi + 1) * x.fi + x.se;
  184. }
  185. tree = Fenwick_Tree(v.size() + 5);
  186. for (int i = 0, j = 0; i < a.size(); i++)
  187. {
  188. while (j < b.size() && b[j].se < a[i].fi)
  189. {
  190. tree.update(get_id(b[j].fi - b[j].se - 2), {1, min(0, b[j].se - b[j].fi + 2 - m)});
  191. j++;
  192. }
  193. ii x = tree.get(get_id(a[i].se - a[i].fi - m));
  194. ans -= (a[i].se - a[i].fi + 1) * x.fi + x.se;
  195. }
  196. // for (ii prx : a)
  197. // for (ii pry : b)
  198. // if (prx.fi < pry.se + 2 - m)
  199. // cout << prx.fi << ' ' << prx.se << ' ' << pry.fi << ' ' << pry.se, el;
  200. cout << ans;
  201. }
  202.  
Success #stdin #stdout 0.01s 5292KB
stdin
Standard input is empty
stdout
Standard output is empty