結果

問題 No.599 回文かい
ユーザー Pachicobue
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#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;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0