Advertisement
Malinovsky239

ICL 2013

Mar 17th, 2013
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.47 KB | None | 0 0
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <string>
  7. #include <vector>
  8. #include <map>
  9. #include <set>
  10. #include <cmath>
  11. #include <ctime>
  12. #include <cassert>
  13.  
  14. using namespace std;
  15.  
  16. #define pb push_back
  17. #define mp make_pair
  18. #define sz(A) (int)(A).size()
  19.  
  20. typedef long long LL;
  21. typedef long double LD;
  22.  
  23. const int MOD = int(1e12 + 7), P = 239017, L = int(1e5 + 5);
  24.  
  25. int len, pos_ans[4], add_right[4], out[4];
  26. char s[2][L], ans[4][2][L];
  27. LL p[L], h[2][L], rh[2][L];
  28.  
  29. void precalc() {
  30.     for (int k = 0; k < 4; k++)
  31.         for (int i = 0; i < 2; i++)
  32.             for (int j = 0; j < len; j++)
  33.                 ans[k][i][j] = '.';
  34.  
  35.     p[0] = 1;
  36.     for (int i = 1; i < L; i++)
  37.         p[i] = (p[i - 1] * P) % MOD;
  38.  
  39.     for (int j = 0; j < 2; j++) {
  40.         h[j][0] = s[j][0];
  41.         for (int i = 1; i < len; i++)
  42.             h[j][i] = (h[j][i - 1] * P + s[j][i]) % MOD;
  43.     }
  44.  
  45.     for (int j = 0; j < 2; j++) {
  46.         rh[j][len - 1] = s[j][len - 1];
  47.         for (int i = len - 2; i >= 0; i--)
  48.             rh[j][i] = (rh[j][i + 1] * P + s[j][i]) % MOD;
  49.     }
  50. }
  51.  
  52. LL count_hash(int num, int l, int r) {
  53.     if (!l)
  54.         return h[num][r];
  55.     LL val = h[num][r] - h[num][l - 1] * p[r - l + 1];
  56.     if (val < 0)
  57.         val += MOD;
  58.     val %= MOD;
  59.     return val;
  60. }
  61.  
  62. LL count_rev_hash(int num, int l, int r) { 
  63.     LL val = rh[num][l] - rh[num][r + 1] * p[r - l + 1];
  64.     if (val < 0)
  65.         val += MOD;
  66.     val %= MOD;
  67.     return val;
  68. }
  69.  
  70. int main()
  71. {
  72. //  freopen(".in", "r", stdin);
  73. //  freopen(".out", "w", stdout);
  74.  
  75.     scanf("%d\n", &len);
  76.     gets(s[0]);
  77.     gets(s[1]);
  78.  
  79.     precalc();
  80.  
  81.     // odd, center in the first row
  82.     int l = 0, r = len;
  83.     while (l + 1 < r) {
  84.         int mid = (l + r) / 2;
  85.         bool ok = 0;
  86.         for (int i = mid; i < len; i++) {
  87.             int l_ = 0, r_ = mid + 1;                      
  88.             while (l_ + 1 < r_) {
  89.                 int mid_ = (l_ + r_) / 2;              
  90.                 if (count_hash(0, i + 1, i + mid_) == count_rev_hash(0, i - mid_, i - 1))
  91.                     l_ = mid_;
  92.                 else
  93.                     r_ = mid_;
  94.             }
  95. //          if (i == 3)
  96. //              cerr << count_rev_hash(0, i - mid, i - l_ - 1) << " " << count_hash(1, i + l_, i + mid - 1) << endl;               
  97.  
  98.             int rest = mid - l_;
  99.             if (count_rev_hash(0, i - mid, i - l_ - 1) == count_hash(1, i + l_, i + mid - 1)) {
  100.                 ok = 1;
  101.                 pos_ans[0] = i;
  102.                 add_right[0] = l_;
  103.                 break;
  104.             }              
  105.         }
  106.         if (ok)
  107.             l = mid;
  108.         else
  109.             r = mid;
  110.     }
  111.  
  112.     out[0] = 2 * l + 1;
  113.     for (int i = pos_ans[0] - l; i <= pos_ans[0] + add_right[0]; i++)
  114.         ans[0][0][i] = s[0][i];
  115.     for (int i = pos_ans[0] + add_right[0]; i < pos_ans[0] + l; i++)
  116.         ans[0][1][i] = s[1][i];
  117.  
  118.     l = 0, r = len;
  119.     while (l + 1 < r) {
  120.         int mid = (l + r) / 2;
  121.         bool ok = 0;
  122.         for (int i = 0; i + mid < len; i++) {
  123.             int l_ = 0, r_ = mid + 1;                      
  124.             while (l_ + 1 < r_) {
  125.                 int mid_ = (l_ + r_) / 2;              
  126.                 if (count_hash(1, i + 1, i + mid_) == count_rev_hash(1, i - mid_, i - 1))
  127.                     l_ = mid_;
  128.                 else
  129.                     r_ = mid_;
  130.             }
  131. //          if (i == 3)
  132. //              cerr << count_rev_hash(0, i - mid, i - l_ - 1) << " " << count_hash(1, i + l_, i + mid - 1) << endl;               
  133.  
  134.             int rest = mid - l_;
  135.             if (count_rev_hash(0, i - mid + 1, i - l_) == count_hash(1, i + l_ + 1, i + mid)) {
  136.                 ok = 1;
  137.                 pos_ans[1] = i;
  138.                 add_right[1] = l_;
  139.                 break;
  140.             }              
  141.         }
  142.         if (ok)
  143.             l = mid;
  144.         else
  145.             r = mid;
  146.     }
  147.  
  148.     out[1] = 2 * l + 1;
  149.     for (int i = pos_ans[1] - l + 1; i <= pos_ans[1] - add_right[1]; i++)
  150.         ans[1][0][i] = s[0][i];
  151.     for (int i = pos_ans[1] - add_right[1]; i <= pos_ans[1] + l; i++)
  152.         ans[1][1][i] = s[1][i];
  153.  
  154.     l = 0, r = len + 1;
  155.     while (l + 1 < r) {
  156.         int mid = (l + r) / 2;
  157.         bool ok = 0;
  158.         for (int i = mid - 1; i < len; i++) {
  159.             int l_ = 0, r_ = mid + 1;                      
  160.             while (l_ + 1 < r_) {
  161.                 int mid_ = (l_ + r_) / 2;              
  162.                 if (count_hash(0, i + 1, i + mid_) == count_rev_hash(0, i - mid_ + 1, i))
  163.                     l_ = mid_;
  164.                 else
  165.                     r_ = mid_;
  166.             }
  167.  
  168.             int rest = mid - l_;
  169.             if (count_rev_hash(0, i - mid + 1, i - l_) == count_hash(1, i + l_, i + mid - 1)) {
  170.                 ok = 1;
  171.                 pos_ans[2] = i;
  172.                 add_right[2] = l_;
  173.                 break;
  174.             }              
  175.         }
  176.         if (ok)
  177.             l = mid;
  178.         else
  179.             r = mid;
  180.     }
  181.  
  182. //  printf("%d\n", 2 * l);
  183.     out[2] = 2 * l;
  184.     for (int i = pos_ans[2] - l + 1; i <= pos_ans[2] + add_right[2]; i++)
  185.         ans[2][0][i] = s[0][i];
  186.     for (int i = pos_ans[2] + add_right[2]; i < pos_ans[2] + l; i++)
  187.         ans[2][1][i] = s[1][i];
  188. //  for (int i = 0; i < 2; i++, printf("\n"))
  189. //      for (int j = 0; j < len; j++)
  190. //          printf("%c", ans[2][i][j]);    
  191.        
  192.     // even, center in the second row
  193.  
  194.     l = 0, r = len + 1;
  195.     while (l + 1 < r) {
  196.         int mid = (l + r) / 2;
  197.         bool ok = 0;
  198.         for (int i = 0; i + mid <= len; i++) {
  199.             int l_ = 0, r_ = mid + 1;                      
  200.             while (l_ + 1 < r_) {
  201.                 int mid_ = (l_ + r_) / 2;              
  202.                 if (count_hash(1, i, i + mid_ - 1) == count_rev_hash(1, i - mid_, i - 1))
  203.                     l_ = mid_;
  204.                 else
  205.                     r_ = mid_;
  206.             }
  207.  
  208.             int rest = mid - l_;
  209.             if (count_rev_hash(0, i - mid + 1, i - l_) == count_hash(1, i + l_, i + mid - 1)) {
  210.                 ok = 1;
  211.                 pos_ans[3] = i;
  212.                 add_right[3] = l_;
  213.                 break;
  214.             }              
  215.         }
  216.         if (ok)
  217.             l = mid;
  218.         else
  219.             r = mid;
  220.     }
  221.  
  222.     out[3] = 2 * l;
  223.     for (int i = pos_ans[3] - l + 1; i <= pos_ans[3] - add_right[3]; i++)
  224.         ans[3][0][i] = s[0][i];
  225.     for (int i = pos_ans[3] - add_right[3]; i <= pos_ans[3] + l - 1; i++)
  226.         ans[3][1][i] = s[1][i];
  227.  
  228.     int mx = -1, ind = -1;
  229.     for (int i = 0; i < 4; i++)
  230.         if (out[i] > mx) {
  231.             mx = out[i];
  232.             ind = i;
  233.         }
  234.  
  235.     printf("%d\n", mx);
  236.  
  237.     for (int i = 0; i < 2; i++, printf("\n"))
  238.         for (int j = 0; j < len; j++)
  239.             printf("%c", ans[ind][i][j]);      
  240.         return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement