結果
| 問題 |
No.2606 Mirror Relay
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-01-12 23:35:16 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 60 ms / 2,000 ms |
| コード長 | 3,196 bytes |
| コンパイル時間 | 3,660 ms |
| コンパイル使用メモリ | 268,060 KB |
| 実行使用メモリ | 52,588 KB |
| 最終ジャッジ日時 | 2024-09-28 00:20:01 |
| 合計ジャッジ時間 | 5,546 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 69 |
ソースコード
#include <bits/stdc++.h>
// #include <x86intrin.h>
using namespace std;
#if __cplusplus >= 202002L
using namespace numbers;
#endif
template<class F>
struct y_combinator_result{
F f;
template<class T> explicit y_combinator_result(T &&f): f(forward<T>(f)){ }
template<class ...Args> decltype(auto) operator()(Args &&...args){ return f(ref(*this), forward<Args>(args)...); }
};
template<class F>
decltype(auto) y_combinator(F &&f){
return y_combinator_result<decay_t<F>>(forward<F>(f));
}
// Each node represents a unique palindromic substring plus 0 and 1 node representing empty even and odd string
// Adjacency_Type: array<int, X> or map<Char_Type, int> where X is the size of the alphabet
template<class Char_Type, class Adjacency_Type>
struct palindrome_automaton{
// Begin States
// len: length of the palindrome
// link: suffix link
// serial_link[u]: longest proper suffix v with len[u] - len[link[u]] != len[v] - len[link[v]]
// depth: # of suffix links till root
// occurence: # of occurences of the palindrome as a longest proper palindromic suffix of a prefix
vector<int> len{0, -1}, link{1, 0}, serial_link{0, 0}, depth{0, 0}, occurence{1, 0};
vector<Adjacency_Type> next = vector<Adjacency_Type>(2);
// End States
vector<Char_Type> s{-1};
vector<int> last{0};
long long palindromic_substring_count = 0;
int new_state(int l, int u){
len.push_back(l);
link.push_back(u);
serial_link.push_back(l - len[u] == len[u] - len[link[u]] ? serial_link[u] : u);
depth.push_back(depth[u] + 1);
next.emplace_back();
occurence.push_back(0);
return (int)len.size() - 1;
}
void extend(const vector<Char_Type> &s){
for(auto c: s) extend(c);
}
void extend(Char_Type c){
s.push_back(c);
int l = last.back();
while(s[(int)s.size() - len[l] - 2] != s.back()) l = link[l];
if(!next[l][c]){
int u = link[l];
while(s[(int)s.size() - len[u] - 2] != s.back()) u = link[u];
int v = new_state(len[l] + 2, next[u][c]);
next[l][c] = v; // Separated for UB in C++14 or below
}
last.push_back(next[l][c]);
palindromic_substring_count += depth[last.back()];
++ occurence[last.back()];
}
int size() const{ // # of states
return (int)len.size();
}
// count: # of occurences of the palindrome
vector<int> count;
vector<vector<int>> inv_link;
void init_count(){
count = occurence, inv_link.assign(size(), {});
for(auto u = 2; u < (int)size(); ++ u) inv_link[link[u]].push_back(u);
auto dfs = [&](auto self, int u)->void{
for(auto v: inv_link[u]) self(self, v), count[u] += count[v];
};
dfs(dfs, 0);
}
};
int main(){
cin.tie(0)->sync_with_stdio(0);
cin.exceptions(ios::badbit | ios::failbit);
vector<int> s;
{
string t;
cin >> t;
for(auto c: t){
s.push_back(c - 'a');
}
}
const int mx = 26;
palindrome_automaton<int, array<int, mx>> aut;
aut.extend(s);
aut.init_count();
vector<long long> res(aut.size());
for(auto s = 0; s < 2; ++ s){
y_combinator([&](auto self, int u)->void{
res[u] += 1LL * aut.count[u] * max(0, aut.len[u]);
for(auto v: aut.inv_link[u]){
if(v <= 1){
continue;
}
res[v] += res[u];
self(v);
}
})(s);
}
cout << ranges::max(res) << "\n";
return 0;
}
/*
*/