Skr - 计蒜客
ps:听说是回文树的模板题,就马上学了一波。理解了fail指针就行了。
建议看WWT的论文;
这两行代码坑我好久:(红色那句一定要放在最后)因为 tp == last 的时候,当前节点的fail指针可能指向自己。
node[tot].fail = node[tp].ch[s[i] - '0']; node[last].ch[s[i] - '0'] = tot;
const int N = 2000006;
const int mod = 1000000007;
const int mod = 1000000007;
LL qpow(LL a, LL b) {
if (!b) return 0;
LL c = 1;
for (; b; a = a * a % mod, b >>= 1) if (b & 1) c = c * a % mod;
return c;
}
if (!b) return 0;
LL c = 1;
for (; b; a = a * a % mod, b >>= 1) if (b & 1) c = c * a % mod;
return c;
}
struct data {
int len, fail;
int ch[10];
};
int len, fail;
int ch[10];
};
struct PldTree {
LL ans;
LL num[N];
LL ans;
LL num[N];
int tot, last;
char s[N];
data node[N];
data node[N];
void Inite() {
tot = last = 1;
node[0].fail = 1;
node[1].len = -1;
num[1] = num[0] = 0;
}
void Insert(int i) {
while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
if (!node[last].ch[s[i] - '0']) {
node[++tot].len = node[last].len + 2;
num[tot] = ((s[i] - '0') * qpow(10, node[last].len + 1) % mod + 10 * num[last] % mod + (s[i] - '0')) % mod;
tot = last = 1;
node[0].fail = 1;
node[1].len = -1;
num[1] = num[0] = 0;
}
void Insert(int i) {
while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
if (!node[last].ch[s[i] - '0']) {
node[++tot].len = node[last].len + 2;
num[tot] = ((s[i] - '0') * qpow(10, node[last].len + 1) % mod + 10 * num[last] % mod + (s[i] - '0')) % mod;
int tp = node[last].fail;
while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;
while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;
node[tot].fail = node[tp].ch[s[i] - '0'];
node[last].ch[s[i] - '0'] = tot;
node[last].ch[s[i] - '0'] = tot;
last = tot;
}
else last = node[last].ch[s[i] - '0'];
}
LL sum() {
ans = 0;
Rep(i, 2, tot) ans = (ans + num[i]) % mod;
return ans;
}
/*
void DFS(int u, LL tp) {
Rep(i, 1, 9) if (node[u].ch[i]) {
LL res = (i * qpow(10, node[u].len + 1) % mod + 10ll * tp % mod + i) % mod;
ans = (ans + res) % mod;
DFS(node[u].ch[i], res);
}
}
*/
};
}
else last = node[last].ch[s[i] - '0'];
}
LL sum() {
ans = 0;
Rep(i, 2, tot) ans = (ans + num[i]) % mod;
return ans;
}
/*
void DFS(int u, LL tp) {
Rep(i, 1, 9) if (node[u].ch[i]) {
LL res = (i * qpow(10, node[u].len + 1) % mod + 10ll * tp % mod + i) % mod;
ans = (ans + res) % mod;
DFS(node[u].ch[i], res);
}
}
*/
};
PldTree T;
int main()
{
T.Inite();
scanf("%s", T.s + 1);
{
T.Inite();
scanf("%s", T.s + 1);
int n = strlen(T.s + 1);
Rep(i, 1, n) T.Insert(i);
Rep(i, 1, n) T.Insert(i);
pr(T.sum());
/*
T.ans = 0;
T.DFS(0, 0);
T.DFS(1, 0);
T.ans = 0;
T.DFS(0, 0);
T.DFS(1, 0);
pr(T.ans);
*/
*/
return 0;
}
}