#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
ll MOD[2] = {(ll)1e9+7,(ll)1e9+9};
ll prefH[300001][2];
ll p[2] = {2137,420691};
ll P[300001][2];
string s;
int n;
ll hash_(int l, int r)
{
ll h0 = (((prefH[r][0] - prefH[l-1][0] + MOD[0]) % MOD[0]) * P[siz(s)-l][0]) % MOD[0];
ll h1 = (((prefH[r][1] - prefH[l-1][1] + MOD[1]) % MOD[1]) * P[siz(s)-l][1]) % MOD[1];
return h0 * MOD[1] + h1;
}
void hash_calc()
{
rep(d,2)
{
P[0][d] = 1;
rep2(i,1,2*siz(s))
{
P[i][d] = (P[i-1][d] * p[d]) % MOD[d];
}
rep2(i,1,siz(s))
{
prefH[i][d] = (prefH[i-1][d] + s[i] * P[i-1][d]) % MOD[d];
}
}
}
struct node
{
int l,r,link = 0, cnt = 0;
vi sons;
};
int node_cnt = 2;
unordered_map<ll,int> node_index;
node nodes[1000001];
int suf_node[600001];
ll ans = 0;
ll dfs(int v)
{
ll sub = nodes[v].cnt;
forall(it,nodes[v].sons)
{
sub += dfs(it);
}
ans = max(ans,sub * (nodes[v].r-nodes[v].l+1));
return sub;
}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//random_start();
cin >> s;
s = "#" + s;
n = siz(s)-1;
nodes[0] = {1,0};
nodes[1] = {0,0};
suf_node[0] = 1;
rep2(z,'a','z')
{
s = s + (char)z;
s = s + (char)z;
}
hash_calc();
int cur_poz = n+1;
rep2(z,'a','z')
{
nodes[0].sons.pb(node_cnt);
nodes[node_cnt] = {cur_poz,cur_poz,0,0};
node_index[hash_(cur_poz,cur_poz)] = node_cnt;
nodes[node_cnt+1] = {cur_poz,cur_poz+1,node_cnt,0};
nodes[node_cnt].sons.pb(node_cnt+1);
node_index[hash_(cur_poz,cur_poz+1)] = node_cnt+1;
node_cnt+=2;
cur_poz+=2;
}
rep2(i,1,n)
{
int cur_node = suf_node[i-1];
while(nodes[cur_node].r >= nodes[cur_node].l)
{
if(s[i-(nodes[cur_node].r-nodes[cur_node].l+1)-1] == s[i])
{
break;
}
cur_node = nodes[cur_node].link;
}
if(nodes[cur_node].r >= nodes[cur_node].l)
{
int len = nodes[cur_node].r - nodes[cur_node].l+2;
ll h = hash_(i-len,i);
if(node_index.find(h) == node_index.end())
{
node_index[h] = node_cnt;
nodes[node_cnt] = {i-len,i,0,1};
cur_node = nodes[cur_node].link;
while(nodes[cur_node].r >= nodes[cur_node].l)
{
if(s[i-(nodes[cur_node].r-nodes[cur_node].l+1)-1] == s[i])
{
break;
}
cur_node = nodes[cur_node].link;
}
if(nodes[cur_node].r >= nodes[cur_node].l)
{
len = nodes[cur_node].r - nodes[cur_node].l+2;
int cur_node = node_index[hash_(i-len,i)];
nodes[node_cnt].link = cur_node;
nodes[cur_node].sons.pb(node_cnt);
}
else
{
int len = 0;
if(s[i] == s[i-1])
{
len = 1;
}
nodes[node_cnt].link = node_index[hash_(i-len,i)];
nodes[nodes[node_cnt].link].sons.pb(node_cnt);
}
node_cnt++;
}
else
{
nodes[node_index[h]].cnt++;
}
suf_node[i] = node_index[h];
}
else
{
int len = 0;
if(s[i] == s[i-1])
{
len = 1;
}
nodes[node_index[hash_(i-len,i)]].cnt++;
suf_node[i] = node_index[hash_(i-len,i)];
}
}
dfs(0);
cout << ans << "\n";
}
# | 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... |