Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.11 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4.  
  5. const int MX = 200000;
  6.  
  7. vector<long long> primes = {999983, 999979};
  8. vector<long long> MODS = {1000000009, 1000000007};
  9.  
  10. long long extendeEuclid ( long long A, long long B, long long *X, long long *Y ){
  11. long long x2, y2, x1, y1, x, y, r2, r1, q, r;
  12. x2 = 1; y2 = 0; x1 = 0; y1 = 1;
  13. for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
  14. q = r2 / r1; r = r2 % r1;
  15. x = x2 - (q * x1); y = y2 - (q * y1);
  16. }
  17. *X = x2; *Y = y2;
  18. return r2;
  19. }
  20.  
  21.  
  22. long long modInv ( long long a, long long m ) {
  23. long long x, y;
  24. long long _ = extendeEuclid( a, m, &x, &y );
  25. x %= m;
  26. if ( x < 0 ) x += m;
  27. return x;
  28. }
  29.  
  30. long long powers[2][MX], powersInv[2][MX];
  31. string S[2];
  32. int N[2];
  33.  
  34. long long hashes[2][2][MX];
  35.  
  36. long long rangeHash(int hashID, int strID, int lft, int rgt) {
  37.  
  38. long long ret = (hashes[hashID][strID][rgt] -
  39. hashes[hashID][strID][lft-1]*powersInv[hashID][lft-1]) % MODS[hashID];
  40.  
  41. if (ret < 0) ret += MODS[hashID];
  42. return ret;
  43. }
  44.  
  45.  
  46. multiset<pair<long long, long long> > possible;
  47.  
  48. bool check(int len) {
  49. cout << "len:" << len << endl;
  50. if (!len) return true;
  51. possible.clear();
  52.  
  53. for (int i = 1, j = len; j <= N[0]; i ++, j ++) {
  54. possible.insert({rangeHash(0, 0, i, j), rangeHash(1, 0, i, j)});
  55. }
  56.  
  57. // for (auto u: possible) {
  58. // cout << "(" << u.first << " " << u.second << ")\n";
  59. // }
  60.  
  61. for (int i = 1, j = len; j <= N[1]; i ++, j ++) {
  62. pair<long long, long long> key = {rangeHash(0, 1, i, j), rangeHash(1, 1, i, j)};
  63. if (possible.find(key) != possible.end()) {
  64. return true;
  65. }
  66. }
  67.  
  68. return false;
  69. }
  70.  
  71. int main() {
  72. freopen("data.in", "r", stdin);
  73.  
  74. ios_base::sync_with_stdio(0); cin.tie(0);
  75.  
  76. cin >> S[0] >> S[1];
  77. N[0] = S[0].size(), N[1] = S[1].size();
  78.  
  79. cout << "N0:" << N[0] << " N1:" << N[1] << endl;
  80.  
  81. vector<long long> primesInv;
  82. for (int i = 0; i < 2; i ++)
  83. primesInv.push_back(modInv(primes[i], MODS[i]));
  84.  
  85. // cout << "movi1:" << primesInv[0] << " movi2:" << primesInv[1] << endl;
  86.  
  87. powers[0][0] = powers[1][0] = powersInv[0][0] = powersInv[1][0] = 1;
  88.  
  89. for (int j = 1; j < MX; j ++) {
  90. for (int i = 0; i < 2; i ++) {
  91.  
  92. powers[i][j] = (powers[i][j-1]*primes[i]) % MODS[i];
  93.  
  94. powersInv[i][j] = (powersInv[i][j-1]*primesInv[i]) % MODS[i];
  95. }
  96.  
  97. }
  98.  
  99.  
  100. for (int i = 0; i < 2; i ++) { // over string
  101. for (int j = 1; j < N[i]; j ++) { // over length
  102. for (int k = 0; k < 2; k ++) { // over primes-hash
  103. hashes[k][i][j] = (hashes[k][i][j-1] + powers[k][j-1]*S[i][j-1]) % MODS[k];
  104. }
  105. }
  106. }
  107.  
  108. int lo = 0, hi = min(N[0], N[1]), ans = -1, mid;
  109.  
  110. while (lo <= hi) {
  111. mid = (lo+hi) / 2;
  112. if (check(mid)) {
  113. ans = mid;
  114. lo = mid + 1;
  115. } else {
  116. hi = mid - 1;
  117. }
  118. }
  119.  
  120. cout << ans;
  121.  
  122. return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement