結果
問題 | No.263 Common Palindromes Extra |
ユーザー | shibh308 |
提出日時 | 2020-07-25 09:55:35 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,977 ms / 2,000 ms |
コード長 | 2,707 bytes |
コンパイル時間 | 4,135 ms |
コンパイル使用メモリ | 208,840 KB |
最終ジャッジ日時 | 2025-01-12 05:20:41 |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
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; 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; }