bkunjesh

B.Password 126B

Jan 10th, 2021 (edited)
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.28 KB | None | 0 0
  1. /*
  2. user:
  3. problem: https://codeforces.com/contest/126/problem/B
  4.  
  5. */
  6.  
  7. #include <bits/stdc++.h>
  8. using namespace std;
  9. #define int long long
  10. #define fast ios_base::sync_with_stdio(0); cin.tie(0);
  11. #define f(i, k) for (int i = 0; i < k; i++)
  12. #define F first
  13. #define dbg(x) cout << #x << " " << x << endl;
  14. #define S second
  15. #define endl "\n"
  16. #define rep(i, n) for (int i = 1; i <= n; i++)
  17. #define rew(i, a, b) for (int i = a; i <= b; i++)
  18. #define mod 1000000007
  19. const int inf = 1e18;
  20. const int N = 200005;
  21.  
  22. // hii there,
  23.  
  24.  
  25. // This question can be solve by two Method:
  26.  
  27. // 1) Using prefix_function
  28. // 2) Rabin-karp + binary search
  29.  
  30. // { Recommendation: Must go through both Method one by one. and give a little bit time to understand. At the end, it's worth to invest little bit time in this question.}
  31.  
  32. // 1. Using prefix_function ( refer https://cp-algorithms.com/string/prefix-function.html#toc-tgt-12 for prefix function)
  33.  
  34.  
  35. //  Problem in simple word:
  36.  
  37. //  We need to find the longest substring T of given string s, which is a prefix, a suffix, and also appears in the middle. Output T or "just a legend" if not present such substring.
  38.  
  39. // We will create an array pi. where pi is prefix array of size n ( ;n=s.size()).
  40.  
  41. // *** pi[i] is the length of the longest prefix of the substring s[0â€Ķi] which is also a suffix of THIS SUBSTRING.
  42.  
  43. // for e.g
  44. //
  45. // let say we have string s= "fixprefixsuffix" . so pi for string s is
  46.  
  47. // index:  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14    
  48. //         f i x p r e f i x s  u  f  f  i  x
  49. // pi:     0 0 0 0 0 0 1 2 3 0  0  1  1  2  3
  50.  
  51. // look at the substring "fixpref"
  52.  
  53. // index:  0 1 2 3 4 5 6  
  54. //         f i x p r e f    
  55. // pi:     0 0 0 0 0 0 1
  56. // pi[6]= 1 because longest prefix which is suffix ending at index 6 is "f"
  57.  
  58. // similarly,
  59. // look at the substring "fixprefi"
  60.  
  61. // index:  0 1 2 3 4 5 6 7  
  62. //         f i x p r e f i    
  63. // pi:     0 0 0 0 0 0 1 2
  64. // pi[7]= 2 because longest prefix which is suffix ending at index 7 is "fi"
  65.  
  66. // in this manner we can find pi array for every index.
  67. // (for algo, refer above link. cp-algorithm has beautiful article on prefix function.)
  68.  
  69. vector<int> prefix_function(string s)
  70. {
  71.     int n = s.size(), i, j;
  72.     vector<int> pi(n + 1);
  73.  
  74.     for (i = 1; i < n; i++)
  75.     {
  76.         j = pi[i - 1];
  77.         while (j > 0 && s[i] != s[j])
  78.             j = pi[j - 1];
  79.         if (s[i] == s[j])
  80.             j++;
  81.         pi[i] = j;
  82.         // cout << pi[i] << " ";
  83.     }
  84.  
  85.     return pi;
  86. }
  87.  
  88. // ***EXPLANATION***
  89.  
  90. // now we want longest substring, which is prefix,suffix and also present in middle
  91. // so let say x=pi[n-1];
  92.  
  93. // now if x is greater than 0 that means
  94. //    we have a prefix of length x which is also suffix right.
  95. //    now we need to check that is that prefix occurs anywhere in the middle of the string or not..
  96.  
  97. //    for this we iterate through the pi array from i= 0 to n-2   (** till n-2 because we know pi[n-1] is already x.)
  98. //    and we search for x in pi ..
  99.  
  100. //    if we find x somewhere in pi
  101. //          that means prefix of length x is also present in between the string s as substring as well as suffix .
  102. //          so we simply output substring of length x (s[0...x])
  103.  
  104. //    if we didn't find x in pi
  105. //           then there is possibility that there exist smaller prefix whose length is less than x which is suffix as well as present in between the string s just like this example:
  106.  
  107. //                  string s= aabcaacdaabcaa
  108. // index:           0 1 2 3 4 5 6 7 8 9 10 11 12 13
  109. //                  a a b c a a c d a a  b  c  a  a
  110. // pi:              0 1 0 0 1 2 0 0 1 2  3  4  5  6
  111. //             we have "aabcaa" {length x=6} as prefix as well as suffix but we did't find it any where in middle of string right
  112. //             so we have to look for prefix of length less than 6(x)
  113. //             we have "aa" {length 2} which satisfy all our need.
  114. //             so now question is how to reach "aa".
  115.  
  116. //             here you need a little bit deeper understanding of prefix function.
  117. //             we will see pi[pi[n-1]-1]
  118. //             lets understand "pi[pi[n-1]-1]" by above example
  119. //             pi[n-1]=6 right so pi[6-1] that is pi[5]=2
  120. //             that means in substring "aabcaa" ( 'cause pi[n-1]=6 )
  121. // index:           0 1 2 3 4 5
  122. //                  a a b c a a
  123. // pi:              0 1 0 0 1 2
  124. //             we have prefix of length 2 which is also suffix right..
  125. //             and from pi[n-1]=6 we know substring "aabcaa" is prefix as well as suffix of string s
  126. //             so we have definitely substring "aa" which occurs in prefix and suffix and also in middle somewhere in string s.
  127. //             so in this case we print prefix "aa".
  128.  
  129. // Anyways, i m good, tell me how r u?(memes only)😂😂
  130.  
  131. // ***QUICK EXPLANATION***
  132.  
  133. //  simply we need to check pi[n-1] is greater than 0 or not:
  134. //  if it is then need to find such j where pi[j]==x  (here x=pi[n-1])
  135. //      if we find such j
  136. //          then output prefix of length x
  137. //      otherwise we see for smaller prefix
  138. //      that is pi[pi[n-1]-1] is greater than 0 or not:
  139. //          if it is then
  140. //              output the prefix of length pi[pi[n-1]-1] (that is pi[x-1])
  141. //          other wise
  142. //              print "Just a legend"
  143.  
  144.  
  145. void solve()
  146. {
  147.     int i, j, k, n;
  148.  
  149.     string s;
  150.     cin >> s;
  151.     auto pi = prefix_function(s);
  152.     n = s.size();
  153.     if (pi[n - 1] == 0)
  154.     {
  155.         cout << "Just a legend" << endl;
  156.         return;
  157.     }
  158.     else
  159.     {
  160.         f(i, n - 1)
  161.         {
  162.             if (pi[i] == pi[n - 1])
  163.             {
  164.                 cout << s.substr(0, pi[n - 1]) << endl;
  165.                 return;
  166.             }
  167.         }
  168.  
  169.         if (pi[pi[n - 1] - 1] == 0)
  170.         {
  171.             cout << "Just a legend" << endl;
  172.             return;
  173.         }
  174.         else
  175.         {
  176.             cout << s.substr(0, pi[pi[n - 1] - 1]) << endl;
  177.             return;
  178.         }
  179.     }
  180.  
  181.     return;
  182. }
  183.  
  184. // (first understand the above method then go for this, although they are different solution but it's just a recommendation)
  185. // 2. Rabin-karp + binary_search
  186. //  https://codeforces.com/contest/126/submission/89824218
  187.  
  188. signed main()
  189. {
  190.     fast int t = 1, i, j, k;
  191.     //cin >> t;
  192.     while (t--)
  193.     {
  194.         solve();
  195.     }
  196.     return 0;
  197. }
  198.  
  199.  
Add Comment
Please, Sign In to add comment