#include<bits/allocator.h>
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,popcnt,lzcnt,tune=native")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int128 __int128_t
#define double long double
#define gcd __gcd
#define lcm(a, b) ((a)/gcd(a, b)*(b))
#define sqrt sqrtl
#define log2 log2l
#define log10 log10l
#define floor floorl
#define to_string str
#define yes cout << "YES"
#define no cout << "NO"
#define trav(i, a) for (auto &i: (a))
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define sz(a) (int)a.size()
#define Max(a) *max_element(all(a))
#define Min(a) *min_element(all(a))
#define Find(a, n) (find(all(a), n) - a.begin())
#define Count(a, n) count(all(a), n)
#define Upper(a, n) (upper_bound(all(a), n) - a.begin())
#define Lower(a, n) (lower_bound(all(a), n) - a.begin())
#define next_perm(a) next_permutation(all(a))
#define prev_perm(a) prev_permutation(all(a))
#define sorted(a) is_sorted(all(a))
#define sum(a) accumulate(all(a), 0)
#define sumll(a) accumulate(all(a), 0ll)
#define Sort(a) sort(all(a))
#define Reverse(a) reverse(all(a))
#define Unique(a) Sort(a), (a).resize(unique(all(a)) - a.begin())
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __buitlin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define open(s) freopen(s, "r", stdin)
#define write(s) freopen(s, "w", stdout)
#define fileopen(s) open((string(s) + ".inp").c_str()), write((string(s) + ".out").c_str());
#define For(i, a, b) for (auto i = (a); i < (b); ++i)
#define Fore(i, a, b) for (auto i = (a); i >= (b); --i)
#define FOR(i, a, b) for (auto i = (a); i <= (b); ++i)
#define ret(s) return void(cout << s);
constexpr int mod = 1e9 + 7, mod2 = 998244353;
constexpr double eps = 1e-9;
const double PI = acos(-1);
constexpr ull npos = string::npos;
constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1}, dy[] = {0, 1, 0, -1, 1, -1, 1, -1};
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using cd = complex<double>;
mt19937 mt(chrono::system_clock::now().time_since_epoch().count());
mt19937_64 mt64(chrono::system_clock::now().time_since_epoch().count());
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<double> vdo;
typedef vector<vdo> vvdo;
typedef vector<string> vs;
typedef vector<pii> vpair;
typedef vector<vpair> vvpair;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<cd> vcd;
typedef priority_queue<int> pq;
typedef priority_queue<int, vi, greater<int>> pqg;
typedef priority_queue<ll> pqll;
typedef priority_queue<ll, vll, greater<ll>> pqgll;
ll add(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);a+=b;return a >= m ? a - m: a;}
ll sub(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);a-=b;return a < 0 ? a + m: a;}
ll mul(ll a, ll b, int m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);return a*b % m;}
ll bin_mul(ll a, ll b, ll m) {a = (a >= m ? a % m: a);b = (b >= m ? b % m: b);ll x = 0;while (b) {if (b & 1) x = (x + a) % m;a = (a + a) % m;b>>=1;}return x;}
ll bin_pow(ll a, ll b, ll m) {ll x = 1;a = (a >= m ? a % m: a); while (b) {if (b & 1) x = bin_mul(x, a, m);a = bin_mul(a, a, m);b>>=1;}return x;}
ll power(ll a, ll b, int m) {ll x = 1;a = (a >= m ? a % m: a); while (b) {if (b & 1) x = x*a % m;a = a*a % m;b>>=1;}return x;}
ll power(ll a, ll b) {ll x = 1;while (b) {if (b & 1) x = x*a;a = a*a;b>>=1;}return x;}
ll ceil(ll a, ll b) {return (a + b - 1)/b;}
ll to_int(const string &s) {ll x = 0; for (int i = (s[0] == '-'); i < sz(s); ++i) x = x*10 + s[i] - '0';return x*(s[0] == '-' ? -1: 1);}
bool is_prime(ll n) {if (n < 2) return 0;if (n < 4) return 1;if (n % 2 == 0 || n % 3 == 0) return 0;for (ll i = 5; i*i <= n; i+=6) {if(n % i == 0 || n % (i + 2) == 0) return 0;}return 1;}
bool is_square(ll n) {ll k = sqrt(n); return k*k == n;}
ll factorial(int n) {ll x = 1;for (int i = 2; i <= n; ++i) x*=i;return x;}
ll factorial(int n, int m) {ll x = 1;for (ll i = 2; i <= n; ++i) x = x*i % m;return x;}
bool is_power(ll n, ll k) {while (n % k == 0) n/=k;return n == 1ll;}
string str(ll n) {if (n == 0) return "0"; string s = ""; bool c = 0; if (n < 0) c = 1, n = -n; while (n) {s+=n % 10 + '0'; n/=10;} if (c) s+='-'; Reverse(s); return s;}
string repeat(const string &s, int n) {if (n < 0) return ""; string x = ""; while (n--) x+=s; return x;}
string bin(ll n) {string s = ""; while (n) {s+=(n & 1) + '0'; n>>=1;} Reverse(s); return s;}
void sieve(vector<bool> &a) {int n = a.size(); a[0] = a[1] = 0; for (int i = 4; i < n; i+=2) a[i] = 0; for (int i = 3; i*i < n; i+=2) {if (a[i]) {for (int j = i*i; j < n; j+=(i << 1)) a[j] = 0;}}}
void sieve(bool a[], int n) {a[0] = a[1] = 0; for (int i = 4; i < n; i+=2) a[i] = 0; for (int i = 3; i*i < n; i+=2) {if (a[i]) {for (int j = i*i; j < n; j+=(i << 1)) a[j] = 0;}}}
void sieve(vector<int> &a) {int n = a.size(); for (int i = 2; i < n; i+=2) a[i] = 2; for (int i = 3; i*i < n; i+=2) {if (!a[i]) {for (int j = i; j < n; j+=(i << 1)) a[j] = i;}} for (int i = 3; i < n; i+=2) {if (!a[i]) a[i] = i;}}
void sieve(int a[], int n) {for (int i = 2; i < n; i+=2) a[i] = 2; for (int i = 3; i*i < n; i+=2) {if (!a[i]) {for (int j = i; j < n; j+=(i << 1)) a[j] = i;}} for (int i = 3; i < n; i+=2) {if (!a[i]) a[i] = i;}}
vector<pii> factorize(int n) {vector<pii> a; for (int i = 2; i*i <= n; ++i) {if (n % i == 0) {int k = 0; while (n % i == 0) ++k, n/=i; a.emplace_back(i, k);}} if (n > 1) a.emplace_back(n, 1); return a;}
int rand(int l, int r) {return uniform_int_distribution<int>(l, r)(mt);}
ll rand(ll l, ll r) {return uniform_int_distribution<ll>(l, r)(mt64);}
int Log2(int n) {return 31 - __builtin_clz(n);}
ll Log2(ll n) {return 63 - __builtin_clzll(n);}
template<class T> void compress(vector<T> &a) {vector<T> b; for (T &i: a) b.push_back(i); sort(all(b)); b.resize(unique(all(b)) - b.begin()); for (T &i: a) i = lower_bound(all(b), i) - b.begin() + 1;}
template<class A, class B> bool ckmin(A &a, const B &b) {return a > b ? a = b, 1: 0;}
template<class A, class B> bool ckmax(A &a, const B &b) {return a < b ? a = b, 1: 0;}
template<class A, class B> istream& operator>>(istream& in, pair<A, B> &p) {in >> p.first >> p.second; return in;}
template<class A, class B> ostream& operator<<(ostream& out, const pair<A, B> &p) {out << p.first << ' ' << p.second; return out;}
template<class T> istream& operator>>(istream& in, vector<T> &a) {for (auto &i: a) in >> i; return in;}
template<class T> ostream& operator<<(ostream& out, const vector<T> &a) {for (auto &i: a) out << i << ' '; return out;}
template<class T> istream& operator>>(istream& in, vector<vector<T>> &a) {for (auto &i: a) in >> i; return in;}
template<class T> ostream& operator<<(ostream& out, const vector<vector<T>> &a) {for (auto &i: a) out << i << '\n'; return out;}
template<class T> istream& operator>>(istream& in, deque<T> &a) {for (auto &i: a) in >> i; return in;}
template<class T> ostream& operator<<(ostream& out, const deque<T> &a) {for (auto &i: a) out << i << ' '; return out;}
// istream& operator>>(istream& in, __int128_t &a) {string s; in >> s; a = 0; for (auto &i: s) a = a*10 + (i - '0'); return in;}
// ostream& operator<<(ostream& out, __int128_t a) {string s = ""; if (a < 0) s+='-', a = -a; if (a == 0) s+='0'; while (a > 0) {s+=(int)(a % 10) + '0'; a/=10;} Reverse(s); out << s; return out;}
template < auto P_ > class MontgomeryModInt
{
using S = decltype(P_); static_assert(is_same_v < S, int > || is_same_v < S, long long >);
static_assert(P_ & 1 && 0 < P_ && P_ < ( (S)1 << ( sizeof(S) * 8 - 2 ) ));
using U = conditional_t < is_same_v < S, int >, unsigned, unsigned long long >; using D = conditional_t < is_same_v < S, int >, unsigned long long, __uint128_t >;
inline constexpr static U uinv(U x) { U y = x; for ( int i = is_same_v < S, int > ? 4 : 5 ; i-- ; ) y *= 2 - x * y; return y; }
constexpr static U P = P_, P2 = P << 1, R = -uinv(P), R2 = -(D)P % P; static_assert(P * R == -1);
inline constexpr static U reduce(D x) { return ( x + (U)x * R * (D)P ) >> ( sizeof(U) * 8 ); }
inline constexpr MontgomeryModInt(U x, int) : v(x) {} U v;
public:
inline constexpr static S mod() { return P; }
inline constexpr MontgomeryModInt() : v(0) {}
inline constexpr MontgomeryModInt(const MontgomeryModInt &x) : v(x.v) {}
template < class T, enable_if_t < numeric_limits < T >::is_integer, int > = 0 > inline constexpr MontgomeryModInt(T x) : v(reduce((D)R2 * ( numeric_limits < T >::is_signed && x < 0 ? ( ( x + P < 0 ) && ( x %= P ), x + P ) : ( ( sizeof(T) > sizeof(U) && x >= (T)1 << sizeof(U) ) && ( x %= P ), x ) ))) {}
inline constexpr S val()const { U x = reduce(v); return ( x - P ) >> ( sizeof(U) * 8 - 1 ) ? x : x - P; }
template < class T, enable_if_t < numeric_limits < T >::is_integer, int > = 0 > explicit inline constexpr operator T()const { return val(); }
inline constexpr friend bool operator==(const MontgomeryModInt &x, const MontgomeryModInt &y) { return x.val() == y.val(); }
inline constexpr friend bool operator!=(const MontgomeryModInt &x, const MontgomeryModInt &y) { return x.val() != y.val(); }
inline constexpr MontgomeryModInt &operator=(const MontgomeryModInt &x) & { v = x.v; return *this; }
inline constexpr MontgomeryModInt &operator++() & { return *this += 1; }
inline constexpr MontgomeryModInt operator++(int) & { MontgomeryModInt x = *this; *this += 1; return x; }
inline constexpr MontgomeryModInt &operator--() & { return *this -= 1; }
inline constexpr MontgomeryModInt operator--(int) & { MontgomeryModInt x = *this; *this -= 1; return x; }
inline constexpr MontgomeryModInt operator-()const { return MontgomeryModInt(v ? P2 - v : 0, 0); }
inline constexpr MontgomeryModInt &operator+=(const MontgomeryModInt &x) & { v += x.v, ( v - P2 ) >> ( sizeof(U) * 8 - 1 ) || ( v -= P2 ); return *this; }
inline constexpr MontgomeryModInt &operator-=(const MontgomeryModInt &x) & { v -= x.v, v >> ( sizeof(U) * 8 - 1 ) && ( v += P2 ); return *this; }
inline constexpr MontgomeryModInt &operator*=(const MontgomeryModInt &x) & { v = reduce((D)v * x.v); return *this; }
inline constexpr MontgomeryModInt &operator/=(const MontgomeryModInt &x) & { return *this *= x.inv(); }
inline constexpr friend MontgomeryModInt operator+(MontgomeryModInt x, const MontgomeryModInt &y) { return x += y; }
inline constexpr friend MontgomeryModInt operator-(MontgomeryModInt x, const MontgomeryModInt &y) { return x -= y; }
inline constexpr friend MontgomeryModInt operator*(MontgomeryModInt x, const MontgomeryModInt &y) { return x *= y; }
inline constexpr friend MontgomeryModInt operator/(MontgomeryModInt x, const MontgomeryModInt &y) { return x /= y; }
template < class T, enable_if_t < numeric_limits < T >::is_integer, int > = 0 > inline constexpr MontgomeryModInt qpow(T y)const { MontgomeryModInt x = *this, z = 1; while ( y ) { if ( y & 1 ) z *= x; if ( y >>= 1 ) x *= x; } return z; }
template < class T, enable_if_t < numeric_limits < T >::is_integer, int > = 0 > inline constexpr friend MontgomeryModInt qpow(const MontgomeryModInt &x, T y) { return x.qpow(y); }
inline constexpr MontgomeryModInt inv()const { return qpow(P - 2); }
inline constexpr friend MontgomeryModInt inv(const MontgomeryModInt &x) { return x.inv(); }
inline friend istream &operator>>(istream &is, MontgomeryModInt &x) { S y; is >> y, x = y; return is; }
inline friend ostream &operator<<(ostream &os, const MontgomeryModInt &x) { return os << x.val(); }
};
using mint = MontgomeryModInt<mod>;
vi suffix_array(string s) {
s+=' ';
int n = sz(s);
vi p(n), c(n), f(max(n, 128));
trav(i,s) f[i]++;
partial_sum(all(f), f.begin());
For(i,0,n) p[--f[s[i]]] = i;
int cl = 1;
For(i,1,n){
if (s[p[i]] != s[p[i - 1]]) ++cl;
c[p[i]] = cl - 1;
}
vi q(n), d(n);
for (int h = 1; h < n; h<<=1) {
For(i,0,n){
q[i] = p[i] - h;
if (q[i] < 0) q[i]+=n;
}
fill(f.begin(), f.begin() + cl, 0);
For(i,0,n) f[c[q[i]]]++;
partial_sum(f.begin(), f.begin() + cl, f.begin());
Fore(i,n-1,0) p[--f[c[q[i]]]] = q[i];
d[p[0]] = 0;
cl = 1;
For(i,1,n){
if (c[p[i]] != c[p[i - 1]] || c[(p[i] + h) % n] != c[(p[i - 1] + h) % n]) ++cl;
d[p[i]] = cl - 1;
}
c.swap(d);
}
p.erase(p.begin());
return p;
}
vi lcp(const string &s, const vi &p) {
int n = sz(s);
vi r(n), l(n - 1);
For(i,0,n) r[p[i]] = i;
int k = 0;
For(i,0,n){
if (r[i] == n - 1) {k = 0; continue;}
int j = p[r[i] + 1];
while (i + k < n && j + k < n && s[i + k] == s[j + k]) ++k;
l[r[i]] = k;
if (k) --k;
}
return l;
}
constexpr int N = 300005, base = 311;
mint pw[N];
struct Hash {
vector<mint> h;
int n;
bool c;
Hash(const string &s, bool c): n(sz(s)), h(sz(s)), c(c) {
h[0] = s[0];
For(i,1,n) h[i] = h[i - 1] + pw[i]*s[i];
}
mint get(int l, int r) {
if (c) tie(l, r) = make_pair(n - r - 1, n - l - 1);
return (h[r] - (l ? h[l - 1]: 0))*pw[n - l];
}
};
struct sparse_min {
int n; vvi s;
int merge(int a, int b) {return a < b ? a: b;}
sparse_min(const vi &a): n(sz(a)), s(__lg(n) + 1, vi(n)) {
for (int i = 0; i < n; ++i) s[0][i] = a[i];
for (int j = 1; (1 << j) <= n; ++j) {
for (int i = 0; i <= n - (1 << j); ++i) {
s[j][i] = merge(s[j - 1][i], s[j - 1][i + (1 << (j - 1))]);
}
}
}
int get(int l, int r) {
if (l > r) return mod;
int i = __lg(r - l + 1);
return merge(s[i][l], s[i][r - (1 << i) + 1]);
}
};
int main() {
ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL);
cout << fixed << setprecision(10);
pw[0] = 1;
For(i,1,N) pw[i] = pw[i - 1]*base;
string s; cin >> s;
int n = sz(s);
if (n == 1) return cout << 1, 0;
Hash h1(s, 0), h2(string(rall(s)), 1);
vi p = suffix_array(s), a = lcp(s, p), q(n);
sparse_min c(a);
For(i,0,n) q[p[i]] = i;
auto cnt = [&](int l, int r) {
int i = q[l], t = r - l + 1, L = i, R = n - 1, u = i, v = i;
while (L <= R) {
int m = (L + R) >> 1;
if (c.get(i, m - 1) >= t) v = m, L = m + 1;
else R = m - 1;
}
L = 0, R = i;
while (L <= R) {
int m = (L + R) >> 1;
if (c.get(m, i - 1) >= t) u = m, R = m - 1;
else L = m + 1;
}
return v - u + 1;
};
auto palodd = [&](int i) {
int l = 0, r = min(i + 1, n - i);
while (l < r) {
int m = (l + r + 1) >> 1;
if (h1.get(i - m, i + m) == h2.get(i - m, i + m)) l = m;
else r = m - 1;
}
return l;
};
auto paleven = [&](int i) {
int l = 0, r = min(i + 1, n - i - 1);
while (l < r) {
int m = (l + r + 1) >> 1;
if (h1.get(i - m, i + m + 1) == h2.get(i - m, i + m + 1)) l = m;
else r = m - 1;
}
return l;
};
set<int> od, ev;
ll x = 1;
For(i,0,n){
Fore(m,palodd(i),0){
if (!od.insert(h1.get(i - m, i + m).val()).second) break;
ckmax(x, (ll)(2*m + 1)*cnt(i - m, i + m));
}
if (i == n - 1 || s[i] != s[i + 1]) continue;
Fore(m,paleven(i),0){
if (!ev.insert(h1.get(i - m, i + m + 1).val()).second) break;
ckmax(x, (ll)(2*m + 2)*cnt(i - m, i + m + 1));
}
}
cout << x;
cerr << "\nProcess returned 0 (0x0) execution time : " << 0.001*clock() << " s";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |