結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
shibh308
|
| 提出日時 | 2020-07-26 08:34:12 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 919 ms / 2,000 ms |
| コード長 | 2,751 bytes |
| コンパイル時間 | 2,718 ms |
| コンパイル使用メモリ | 210,300 KB |
| 最終ジャッジ日時 | 2025-01-12 05:49:26 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
struct EerTree{
struct Node{
Node(int len) : len(len), sdep(0), slink(nullptr), cnt(0){}
int len, sdep;
map<char, Node*> ch;
Node* slink;
int cnt;
};
pair<Node*, Node*> root;
Node* active_point;
string s;
EerTree(){
root.second = new Node(0);
root.second->slink = root.first = active_point = new Node(-1);
root.first->slink = root.first;
}
EerTree(string inp) : EerTree(){
for(auto c : inp)
add(c);
}
Node* make(Node* par, char c){
if(par->ch.find(c) == par->ch.end()){
par->ch[c] = new Node(par->len + 2);
Node* sl = par->slink;
if(par->len == -1)
sl = root.second;
else{
while(1){
if(s[s.size() - sl->len - 2] == c){
sl = sl->ch[c];
break;
}else if(sl->len < 0){
sl = root.second;
break;
}else
sl = sl->slink;
}
}
par->ch[c]->slink = sl;
par->ch[c]->sdep = sl->sdep + 1;
}
return par->ch[c];
}
void add(char c){
for(s += c; int(s.size()) - active_point->len - 2 < 0 || s[s.size() - active_point->len - 2] != c; active_point = active_point->slink);
active_point = make(active_point, c);
}
};
long long search(EerTree::Node* x, EerTree::Node* y){
long long cnt = 1LL * x->cnt * y->cnt;
if(x->len <= 0)
cnt = 0;
for(auto child : x->ch){
if(y->ch.find(child.first) != y->ch.end()){
cnt += search(x->ch[child.first], y->ch[child.first]);
}
}
return cnt;
}
void dump(EerTree::Node* x, std::vector<EerTree::Node*>& v){
v.emplace_back(x);
for(auto child : x->ch)
dump(child.second, v);
}
signed main(){
string s, t;
cin >> s >> t;
EerTree es, et;
for(auto c : s){
es.add(c);
es.active_point->cnt += 1;
}
for(auto c : t){
et.add(c);
et.active_point->cnt += 1;
}
std::vector<EerTree::Node*> sv, tv;
dump(es.root.first, sv);
dump(es.root.second, sv);
dump(et.root.first, tv);
dump(et.root.second, tv);
sort(sv.begin(), sv.end(), [](auto x, auto y){return x->sdep > y->sdep;});
for(auto x : sv)
x->slink->cnt += x->cnt;
sort(tv.begin(), tv.end(), [](auto x, auto y){return x->sdep > y->sdep;});
for(auto x : tv)
x->slink->cnt += x->cnt;
cout << search(es.root.first, et.root.first) + search(es.root.second, et.root.second) << endl;
}
shibh308