简单题意, 找两个字符串, A B,
A, B 都是回文串, A 是 B 的子串,
A 和 B 的位置任意,可以相同,
f[x] 为 A 的长度为 x , 的 A B 的对数.
根据回文树的性质,
如果A 是B 的子串,
那么一定会有一条路径, B 找它的父亲,然后直接 fail 指向 A.
所以我们只要考虑, A 的子树, fail 指针指向 A 的那些节点的子树.
有可能有多个节点的fail 指向同一个 节点,
多个节点有可能会算重复,这个就需要我们判断重复了.
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+100;
char s[N];
int n,base,mod;
long long f[N];
namespace PAM {
int sz, fl[N], len[N], ch[N][26],cnt[N],vis[N],l[N];
char *s;
int find(int x, int y) {
return s[y] == s[y - len[x] - 1] ? x : find(fl[x], y);
}
void cal(char *str) {
s = str;
int n = strlen(s + 1);
for (int i = 0; i <= n + 2; ++i){
fl[i] = cnt[i] = 0;
for (int j = 0; j < 26; ++j)
ch[i][j] = 0;
}
int now = 0;
sz = 1;
fl[0] = 1;
len[0] = 0; len[1] = -1;
for (int i = 1; i <= n; i++) {
now = find(now, i);
if (!ch[now][s[i] - 'a']) {
len[++sz] = len[now] + 2;
fl[sz] = ch[find(fl[now], i)][s[i] - 'a'];
ch[now][s[i] - 'a'] = sz;
}
now = ch[now][s[i] - 'a'];
cnt[now]++;
l[now] = i;
}
for (int i = sz; i > 1; --i){
cnt[fl[i]] += cnt[i];
}
}
long long size[N],num[N];
void dfs1(int u){
num[u] = cnt[u];
for (int i = 0; i < 26; ++i){
if (ch[u][i]) dfs1(ch[u][i]), num[u] = (num[u] + num[ch[u][i]] ) % mod;
}
}
void dfs(int u){
size[u] = (size[u] + num[u] * cnt[u]) % mod;
if (vis[fl[u]] == 0) size[fl[u]] = (size[fl[u]] + 1ll*num[u] * cnt[fl[u]]) % mod;
vis[fl[u]]++; vis[u]++;
for(int i = 0; i < 26; ++i){
if (ch[u][i]) dfs(ch[u][i]);
}
vis[fl[u]]--; vis[u]--;
}
long long solve(){
for (int i = 0; i <= sz; ++i) size[i] = 0;
long long ans = 0;
dfs1(1); dfs1(0);
dfs(1); dfs(0);
for (int i = 2; i <= sz; ++i){
ans = (ans + 1ll*size[i]*f[n-len[i]]) % mod;
}
return ans;
}
};
int main(){
int T;
scanf("%d",&T);
for (int cas = 1; cas <= T; ++cas){
scanf("%d%d%d",&n,&base,&mod);
f[0] = 1;
for (int i = 1; i <= n; ++i)
f[i] = (f[i-1]*base) % mod;
scanf("%s",s+1);
PAM::cal(s);
printf("Case %d: %lld\n",cas,PAM::solve());
}
return 0;
}
/*
5
13 100 999
welcometomist
7 1000 1000000000
topspot
11 23167 21898192
abbabobaxab
21 123456 123456789
amanaplanacanalpanama
32 72817 728917897
bobxyxthehtxyxbuildercantfixyxit
*/