cf7D
Posted arg-53
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf7D相关的知识,希望对你有一定的参考价值。
题目
http://codeforces.com/contest/7/problem/D
题解
先求出每个点的回文串半径。对于当前所在的前缀,若整个前缀回文,那么前半段后半段一定是对称的对吧,于是不用考虑后半段,当前前缀整段的 k 值一定是前半段 k 值加一。这样把每个前缀的 k 值存一下搞搞,没了。
话说 petr 比赛时用哈希乱搞代码贼短跑得贼快,我见到回文串就无脑 manacher。。还是要学习一个。。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; ++i)
char S[5000010];
int res[10000010], cnt[5000010];
bool ok[5000010];
int main() {
scanf("%s", S);
int N = strlen(S);
int l = -1, r = -1;
rep(z, 2 * N) {
int i = (z + 1) >> 1;
int j = z >> 1;
int p = i >= r ? 0 : min(r - i, res[2 * (l + r) - z]);
while (i - p - 1 >= 0 && j + p + 1 < N) {
if (S[i - p - 1] != S[j + p + 1]) break;
++p;
}
if (j + p > r) {
r = j + p;
l = i - p;
}
res[z] = p;
}
int ans = 1;
cnt[0] = 1;
ok[0] = true;
for (int i = 1; i < N; ++i) {
int c1 = i >> 1;
int c2 = (i & 1 ? c1 : c1 - 1);
int cid1 = (c1 << 1 | (i & 1));
assert(c1 >= 0 && c2 >= 0 && cid1 >= 0);
if (res[cid1] + c1 >= i) {
cnt[i] = 1;
ok[i] = true;
if (ok[c2]) cnt[i] += cnt[c2];
}
ans += cnt[i];
}
printf("%d\n", ans);
}
以上是关于cf7D的主要内容,如果未能解决你的问题,请参考以下文章