結果
| 問題 |
No.599 回文かい
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-11-25 00:40:43 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,956 ms / 4,000 ms |
| コード長 | 3,251 bytes |
| コンパイル時間 | 2,426 ms |
| コンパイル使用メモリ | 207,576 KB |
| 最終ジャッジ日時 | 2025-01-05 04:25:47 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
os << "sz=" << v.size() << "\n[";
for (const auto& p : v) {
os << p << ",";
}
os << "]\n";
return os;
}
template <typename S, typename T>
ostream& operator<<(ostream& os, const pair<S, T>& p)
{
os << "(" << p.first << "," << p.second
<< ")";
return os;
}
constexpr ll MOD = 1e9 + 7;
template <typename T>
constexpr T INF = numeric_limits<T>::max() / 100;
template <typename Container, typename HashType = ll, HashType mod1 = static_cast<HashType>(1000000007), HashType mod2 = static_cast<HashType>(1000000009), HashType add1 = static_cast<HashType>(1000010007), HashType add2 = static_cast<HashType>(1003333331)>
class RollingHash
{
public:
static constexpr HashType MOD1 = mod1;
static constexpr HashType MOD2 = mod2;
using T = HashType;
RollingHash(const Container& original) : size(original.size()), mt{random_device{}()}, base1{getRand1()}, base2{getRand2()}, pow1(size + 1, 1), pow2(size + 1, 1), accum_hash1(size + 1, 0), accum_hash2(size + 1, 0)
{
for (int i = 1; i <= size; i++) {
pow1[i] = (pow1[i - 1] * base1) % mod1;
accum_hash1[i] = (accum_hash1[i - 1] * base1 + add1 + static_cast<T>(original[i - 1])) % mod1;
}
for (int i = 1; i <= size; i++) {
pow2[i] = (pow2[i - 1] * base2) % mod2;
accum_hash2[i] = (accum_hash2[i - 1] * base2 + add2 + static_cast<T>(original[i - 1])) % mod2;
}
}
pair<T, T> getHash(const int l, const int r) const // [l,r)
{
const T h1 = (((accum_hash1[r] - accum_hash1[l] * pow1[r - l]) % mod1) + mod1) % mod1;
const T h2 = (((accum_hash2[r] - accum_hash2[l] * pow2[r - l]) % mod2) + mod2) % mod2;
return make_pair(h1, h2);
}
private:
T getRand1()
{
static T value = 0;
static uniform_int_distribution<T> dist{2, mod1 - 1};
if (value == 0) {
value = dist(mt);
}
return value;
}
T getRand2()
{
static T value = 0;
static uniform_int_distribution<T> dist{2, mod2 - 1};
if (value == 0) {
value = dist(mt);
}
return value;
}
const int size;
mt19937 mt;
const T base1;
const T base2;
vector<T> pow1;
vector<T> pow2;
vector<T> accum_hash1;
vector<T> accum_hash2;
};
map<int, ll> mp;
ll rec(const string& s, const int l, const RollingHash<string>& hash)
{
if (mp.find(l) != mp.end()) {
return mp[l];
}
// cerr << l << endl;
ll sum = 1;
for (int i = s.size() / 2 - l; i >= 1; i--) {
if (hash.getHash(l, l + i) == hash.getHash(s.size() - l - i, s.size() - l)) {
const ll v = rec(s, l + i, hash);
sum += v;
sum %= MOD;
}
}
mp[l] = sum;
return sum;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
string s;
cin >> s;
RollingHash<string> hash(s);
cout << rec(s, 0, hash) << endl;
return 0;
}