結果
問題 | No.599 回文かい |
ユーザー |
![]() |
提出日時 | 2018-09-14 14:07:50 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 1,331 ms / 4,000 ms |
コード長 | 3,386 bytes |
コンパイル時間 | 1,157 ms |
コンパイル使用メモリ | 109,872 KB |
実行使用メモリ | 9,856 KB |
最終ジャッジ日時 | 2024-07-05 03:25:56 |
合計ジャッジ時間 | 9,741 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 22 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <cmath>#include <stack>#include <queue>#include <set>#include <map>#include <unordered_map>#include <chrono>#include <random>#include <iterator>#include <functional>#include <utility>#include <cassert>#pragma GCC optimize("O3")#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")#pragma comment(linker, "STACK:36777216")using namespace std;using i64 = int64_t;constexpr i64 MOD = 1e9 + 7;mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());using vi = vector<i64>;using vvi = vector<vi>;using vvvi = vector<vvi>;using ii = pair<i64, i64>;using i128 = __int128_t;i64 modpow(i128 a, i128 n, i128 mod) {if (n == 0) return 1;if (n % 2 == 0) {i128 t = modpow(a, n / 2, mod);return t * t % mod;}return a * modpow(a, n - 1, mod) % mod;}i128 modinv(i128 n, i128 mod) {return modpow(n, mod - 2, mod);}bool is_prime(i128 n, int k) {if (n == 2) return true;if (n < 2 || n % 2 == 0) return false;i128 d = n - 1;while (d % 2 == 0) {d /= 2;}for (int i = 0; i < k; i++) {i128 a = rnd() % (n - 2) + 1;i128 t = d;i128 y = modpow(a, t, n);while (t != n - 1 && y != 1 && y != n - 1) {y = modpow(y, 2, n);t *= 2;}if (y != n - 1 && t % 2 == 0) {return false;}}return true;}i64 gen_prime(int bit) {assert(bit > 32);while (1) {i128 d = (i128(rnd()) << (bit - 32)) + rnd();d |= 1;if (is_prime(d, 50)) {return d;}}}class RollingHash {i128 hash[202020];i128 pows[202020];i128 p, m;public:RollingHash(string s, i64 p = gen_prime(40), i64 m = gen_prime(50)) {assert(s.size() < 202020);hash[0] = 1;pows[0] = 1;for (int i = 0; i < s.size(); i++) {hash[i + 1] = (hash[i] * p + s[i]) % m;pows[i + 1] = pows[i] * p % m;}this->p = p;this->m = m;}i128 encode(int l, int r) {// inclusivereturn ((hash[r + 1] - hash[l] * pows[r - l + 1]) % m + m) % m;}bool eq(int l0, int r0, int l1, int r1) {return encode(l0, r0) == encode(l1, r1);}};int main() {string s;cin >> s;int n = s.size();RollingHash hash(s);if (n % 2) {vi dp(n / 2 + 1, 1);for (int i = 1; i <= n / 2; i++) {int l = n / 2 - i;int r = n / 2 + i;for (int d = 0; d < i; d++) {if (hash.eq(l, l + d, r - d, r)) {assert(i - 1 - d >= 0);dp[i] += dp[i - 1 - d];dp[i] %= MOD;}}}cout << dp[n / 2] << endl;} else {vi dp(n / 2 + 1, 1);for (int i = 1; i <= n / 2; i++) {int l = n / 2 - i;int r = n / 2 - 1 + i;assert(r > l);for (int d = 0; d < i; d++) {if (hash.eq(l, l + d, r - d, r)) {assert(i - 1 - d >= 0);dp[i] += dp[i - 1 - d];dp[i] %= MOD;}}}cout << dp[n / 2] << endl;}}