bingxuan9112

SA

Nov 23rd, 2019
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.98 KB | None | 0 0
  1. //   __________________
  2. //  | ________________ |
  3. //  ||          ____  ||
  4. //  ||   /\    |      ||
  5. //  ||  /__\   |      ||
  6. //  || /    \  |____  ||
  7. //  ||________________||
  8. //  |__________________|
  9. //  \###################\
  10. //   \###################\
  11. //    \        ____       \
  12. //     \_______\___\_______\
  13. // An AC a day keeps the doctor away.
  14.  
  15. #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
  16. #pragma loop_opt(on)
  17. #include <bits/extc++.h>
  18. #ifdef local
  19. #define debug(x) (cerr<<#x<<" = "<<(x)<<'\n')
  20. #else
  21. #define debug(x) ((void)0)
  22. #endif // local
  23. #define all(v) begin(v),end(v)
  24. #define siz(v) (ll(v.size()))
  25. #define get_pos(v,x) (lower_bound(all(v),x)-begin(v))
  26. #define sort_uni(v) sort(begin(v),end(v)),v.erase(unique(begin(v),end(v)),end(v))
  27. #define pb emplace_back
  28. #define ff first
  29. #define ss second
  30. #define mid (l+(r-l>>1))
  31. #define mem(v,x) memset(v,x,sizeof v)
  32.  
  33. using namespace std;
  34. using namespace __gnu_pbds;
  35. typedef int64_t ll;
  36. typedef long double ld;
  37. typedef pair<ll,ll> pll;
  38. typedef pair<ld,ld> pld;
  39. template <typename T> using max_heap = __gnu_pbds::priority_queue<T,less<T> >;
  40. template <typename T> using min_heap = __gnu_pbds::priority_queue<T,greater<T> >;
  41. template <typename T> using rbt = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
  42. constexpr ld PI = acos(-1), eps = 1e-9;
  43. constexpr ll N = 100025, INF = 1e18, MOD = 20191126, K = 4, inf = 1e9;
  44. constexpr ll modpow(ll e,ll p,ll m=MOD) {ll r=1; for(;p;p>>=1,e=e*e%m) if(p&1) r=r*e%m; return r;}
  45. constexpr inline ll cdiv(ll x, ll m) { return (x+m-1)/m; } // ceiling divide, x/m for flooring divide
  46. template <typename T> void M(T &x, ll m=MOD){x%=m; if(x<0) x+=m;}
  47.  
  48. string s;
  49. struct SuffixArray {
  50.     int sa[N],rk[N],tmp[N],n,LCP[N];
  51.     void solve(const string &s) {
  52.         n = s.size();
  53.         iota(sa,sa+n,0);
  54.         for(int i = 0; i < n; i++) rk[i] = s[i];
  55.         for(int L = 1; L < n; L *= 2) { // sort by the prefix [0:L]
  56.             auto cmp = [&](int a,int b){
  57.                 if(rk[a] != rk[b]) return rk[a]<rk[b];
  58.                 int ra = (a+L<n ? rk[a+L] : -1);
  59.                 int rb = (b+L<n ? rk[b+L] : -1);
  60.                 return ra<rb;
  61.             };
  62.             sort(sa,sa+n,cmp);
  63.             tmp[sa[0]] = 0;
  64.             for(int i = 1; i < n; i++) tmp[sa[i]] = (tmp[sa[i-1]]+cmp(sa[i-1],sa[i]));
  65.             for(int i = 0; i < n; i++) rk[i] = tmp[i];
  66.         }
  67.         for(int i = 0; i < n; i++) sa[rk[i]] = i;
  68.         //for(int i = 0; i < n; i++) cout << s.substr(sa[i], n-sa[i]) << '\n';
  69.         //return;
  70.         for(int i = 0, j, h=0; i < n; i++) {
  71.             if(rk[i] == 0) continue;
  72.             if(h > 0) --h;
  73.             for(int j = sa[rk[i]-1]; i+h < n && j+h < n && s[i+h]==s[j+h]; h++);
  74.             LCP[rk[i]] = h;
  75.         }
  76.         int i = max_element(LCP,LCP+n)-LCP;
  77.         cout << s.substr(sa[i], LCP[i]) << '\n';
  78.     }
  79. } SA;
  80. signed main() {
  81.     ios_base::sync_with_stdio(0), cin.tie(0);
  82.     cin >> s;
  83.     SA.solve(s);
  84. }
Advertisement
Add Comment
Please, Sign In to add comment