Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // __________________
- // | ________________ |
- // || ____ ||
- // || /\ | ||
- // || /__\ | ||
- // || / \ |____ ||
- // ||________________||
- // |__________________|
- // \###################\
- // \###################\
- // \ ____ \
- // \_______\___\_______\
- // An AC a day keeps the doctor away.
- #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
- #pragma loop_opt(on)
- #include <bits/extc++.h>
- #ifdef local
- #define debug(x) (cerr<<#x<<" = "<<(x)<<'\n')
- #else
- #define debug(x) ((void)0)
- #endif // local
- #define all(v) begin(v),end(v)
- #define siz(v) (ll(v.size()))
- #define get_pos(v,x) (lower_bound(all(v),x)-begin(v))
- #define sort_uni(v) sort(begin(v),end(v)),v.erase(unique(begin(v),end(v)),end(v))
- #define pb emplace_back
- #define ff first
- #define ss second
- #define mid (l+(r-l>>1))
- #define mem(v,x) memset(v,x,sizeof v)
- using namespace std;
- using namespace __gnu_pbds;
- typedef int64_t ll;
- typedef long double ld;
- typedef pair<ll,ll> pll;
- typedef pair<ld,ld> pld;
- template <typename T> using max_heap = __gnu_pbds::priority_queue<T,less<T> >;
- template <typename T> using min_heap = __gnu_pbds::priority_queue<T,greater<T> >;
- template <typename T> using rbt = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
- constexpr ld PI = acos(-1), eps = 1e-9;
- constexpr ll N = 100025, INF = 1e18, MOD = 20191126, K = 4, inf = 1e9;
- 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;}
- constexpr inline ll cdiv(ll x, ll m) { return (x+m-1)/m; } // ceiling divide, x/m for flooring divide
- template <typename T> void M(T &x, ll m=MOD){x%=m; if(x<0) x+=m;}
- string s;
- struct SuffixArray {
- int sa[N],rk[N],tmp[N],n,LCP[N];
- void solve(const string &s) {
- n = s.size();
- iota(sa,sa+n,0);
- for(int i = 0; i < n; i++) rk[i] = s[i];
- for(int L = 1; L < n; L *= 2) { // sort by the prefix [0:L]
- auto cmp = [&](int a,int b){
- if(rk[a] != rk[b]) return rk[a]<rk[b];
- int ra = (a+L<n ? rk[a+L] : -1);
- int rb = (b+L<n ? rk[b+L] : -1);
- return ra<rb;
- };
- sort(sa,sa+n,cmp);
- tmp[sa[0]] = 0;
- for(int i = 1; i < n; i++) tmp[sa[i]] = (tmp[sa[i-1]]+cmp(sa[i-1],sa[i]));
- for(int i = 0; i < n; i++) rk[i] = tmp[i];
- }
- for(int i = 0; i < n; i++) sa[rk[i]] = i;
- //for(int i = 0; i < n; i++) cout << s.substr(sa[i], n-sa[i]) << '\n';
- //return;
- for(int i = 0, j, h=0; i < n; i++) {
- if(rk[i] == 0) continue;
- if(h > 0) --h;
- for(int j = sa[rk[i]-1]; i+h < n && j+h < n && s[i+h]==s[j+h]; h++);
- LCP[rk[i]] = h;
- }
- int i = max_element(LCP,LCP+n)-LCP;
- cout << s.substr(sa[i], LCP[i]) << '\n';
- }
- } SA;
- signed main() {
- ios_base::sync_with_stdio(0), cin.tie(0);
- cin >> s;
- SA.solve(s);
- }
Advertisement
Add Comment
Please, Sign In to add comment