#include #include #include #include #include #include using namespace std; class Rolling_Hash{ public: int N; vector p_pow; const int P; const int MOD; vector> hash; Rolling_Hash(const int n) : P(vector{10009, 10007}[0/*rand()%2*/]), MOD(vector{1000000007, 1000000009}[0/*rand()%2*/]), N(n), p_pow(n+1) { p_pow[0] = 1; for(int i=1; i<=N; i++){ p_pow[i] = (1LL * p_pow[i-1] * P) % MOD; } } // [l,r) long long get_hash(int at, int l, int r){ if(r>=hash[at].size()) return -at; int len = r-l; return (hash[at][r] - (1LL * hash[at][l]* p_pow[len])%MOD + MOD) % MOD; } void insert(const string& s){ //hash[i] = [0,i) hash.push_back({}); hash.back().resize(s.size()+1); int at = hash.size() - 1; for(int i=0; i& s, int x, int y){ /* int lb = 0; int ub = s[x].size(); while(ub-lb>1){ int mid = (lb+ub)/2; int hash_x = hash.get_hash(x, 0,mid); int hash_y = hash.get_hash(y, 0,mid); bool ok = hash_x != hash_y; if(ok){ ub = mid; }else{ lb = mid; } } return ub; */ int ret = 0; while(ret> n; vector s(n); int m = 0; for(int i=0; i> s[i]; s[i] += 'a'-1; m = max(m, (int)s[i].size()); } vector x(n); for(int i=0; i> x[i]; x[i]--; } vector> v(n); for(int i=0; i index(n); vector order(n); for(int i=0; i w; Rolling_Hash hash(m); for(int i=0; i ans(n); for(int i=n-1; i>=0; i--){ auto itr = w.insert(order[x[i]]).first; int lcp_len = 1; if(itr != w.begin()){ itr--; lcp_len = max(lcp_len, lcp(hash,s, x[i], index[*itr])); itr++; } itr++; if(itr != w.end()){ lcp_len = max(lcp_len, lcp(hash,s, x[i], index[*itr])); } ans[i] = lcp_len; } for(int i=0; i