結果
| 問題 |
No.263 Common Palindromes Extra
|
| コンテスト | |
| ユーザー |
Ricky_pon
|
| 提出日時 | 2022-06-08 15:18:14 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 142 ms / 2,000 ms |
| コード長 | 3,465 bytes |
| コンパイル時間 | 2,278 ms |
| コンパイル使用メモリ | 210,000 KB |
| 最終ジャッジ日時 | 2025-01-29 19:03:09 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
#include <bits/stdc++.h>
#include <map>
#include <string>
#include <vector>
namespace rklib {
struct PalindromicTree {
const int rootm1 = 0, root0 = 1;
std::vector<int> len = {-1, 0}, link = {rootm1, rootm1};
std::vector<std::map<char, int>> nxt = {{}, {}};
int sz = 2, last = root0;
std::string s;
PalindromicTree() {}
PalindromicTree(std::string& t) {
for (auto c : t) add(c);
}
void create_node() {
++sz;
len.resize(sz);
link.resize(sz);
nxt.resize(sz);
}
void add(char c) {
while (last != rootm1) {
int idx = int(s.size()) - len[last] - 1;
if (idx >= 0 && s[idx] == c) break;
last = link[last];
}
if (nxt[last].find(c) != nxt[last].end()) {
last = nxt[last][c];
s += c;
return;
}
create_node();
int now = sz - 1;
len[now] = len[last] + 2;
int p = link[last];
while (p != rootm1) {
int idx = int(s.size()) - len[p] - 1;
if (idx >= 0 && s[idx] == c) break;
p = link[p];
}
link[now] = (nxt[p].find(c) == nxt[p].end() ? root0 : nxt[p][c]);
nxt[last][c] = now;
last = now;
s += c;
}
std::vector<int> count(std::string& t) {
std::vector<int> res(sz, 0);
int now = rootm1;
for (int i = 0; i < int(t.size()); ++i) {
char c = t[i];
if (nxt[rootm1].find(c) == nxt[rootm1].end()) now = rootm1;
while (now != rootm1) {
int idx = i - len[now] - 1;
if (idx >= 0 && t[idx] == c &&
nxt[now].find(c) != nxt[now].end())
break;
now = link[now];
}
now = (nxt[now].find(c) == nxt[now].end() ? root0 : nxt[now][c]);
++res[now];
}
for (int i = int(res.size()) - 1; i >= 1; i--) {
res[link[i]] += res[i];
}
return res;
}
};
} // namespace rklib
#include <algorithm>
#include <cassert>
#include <vector>
namespace rklib {
template <class T>
bool chmax(T &a, const T &b) {
if (a < b) {
a = b;
return true;
}
return false;
}
template <class T>
bool chmin(T &a, const T &b) {
if (a > b) {
a = b;
return true;
}
return false;
}
template <class T>
bool chmin_non_negative(T &a, const T &b) {
if (a < 0 || a > b) {
a = b;
return true;
}
return false;
}
template <class T>
T div_floor(T a, T b) {
if (b < 0) a *= -1, b *= -1;
return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
if (b < 0) a *= -1, b *= -1;
return a > 0 ? (a - 1) / b + 1 : a / b;
}
} // namespace rklib
#define For(i, a, b) for (int i = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int i = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For(i, 0, n)
#define rrep(i, n) rFor(i, n, 0)
#define fi first
#define se second
using namespace std;
using namespace rklib;
using lint = long long;
using pii = pair<int, int>;
using pll = pair<lint, lint>;
int main() {
string s, t;
cin >> s >> t;
PalindromicTree pt(s);
auto cnt_s = pt.count(s);
auto cnt_t = pt.count(t);
lint ans = 0;
For(i, 2, cnt_s.size()) ans += lint(cnt_s[i]) * lint(cnt_t[i]);
printf("%lld\n", ans);
}
Ricky_pon