版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccsu_cat/article/details/83622879
引用:
Palindromic Tree——回文树【处理一类回文串问题的强力工具】
代码取自:回文树代码模板
#include "cstdio"
#include "algorithm"
#include "cstring"
#define maxn 10000005
#define sigma 26
struct ptree{
char s[maxn];
int next[maxn][sigma],fail[maxn],cnt[maxn],len[maxn];
int last,n,p;
long long res;
inline int newnode(int l){
cnt[p]=0;
len[p]=l;
return p++;
}
inline void init(){
newnode(0),newnode(-1);//two roots
s[n]=-1;
fail[0]=1;
}
inline int FL(int x){
while(s[n-len[x]-1]!=s[n]) x=fail[x];
return x;
}
void add(char c){
c-='a';
s[++n]=c;
int cur=FL(last);
if(!next[cur][c]){
int now=newnode(len[cur]+2);
fail[now]=next[FL(fail[cur])][c];
next[cur][c]=now;
}
last=next[cur][c];
++cnt[last];
}
inline unsigned long long count(){
unsigned long long pk=0;
for(int i=p-1;~i;--i){
cnt[fail[i]]+=cnt[i];
pk+=((unsigned long long)cnt[i])*len[i];
}
return pk;
}
} p;
char s[maxn];
int i,j,k;
int main(){
scanf("%s",s);
j=strlen(s);
p.init();
for(i=0;i<j;++i) p.add(s[i]);
printf("%llu\n",p.count());
return 0;
}
题意:给你一个数字串,求所有本质不同的回文数字串的和%1e9+7
学会回文树后,这题就变成水题了,只需在每次插入的时候,如果插入的是一个新节点,那么新节点num代表的数字可以由父亲*10+num*10^(len-1)+num得到,然后加到答案即可,len表示这个节点代表的回文数字串的长度。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+7,maxn=2e6+10;
ll ans=0,po[maxn];
struct pal
{
char s[maxn];
int next[maxn][10],fail[maxn],len[maxn];
int last,n,p;
ll res[maxn];
int newnode(int l)
{
len[p]=l;
return p++;
}
void init()
{
newnode(0),newnode(-1);
s[n]=-1;
fail[0]=1;
}
int FL(int x)
{
while(s[n-len[x]-1]!=s[n])x=fail[x];
return x;
}
void add(char c)
{
int num=c-'0';
c-='0';
s[++n]=c;
int cur=FL(last);
if(!next[cur][c])
{
int now=newnode(len[cur]+2);
fail[now]=next[FL(fail[cur])][c];
next[cur][c]=now;
if(cur!=1)
res[now]=(po[len[cur]+2]*c+c+res[cur]*10)%mod;
else
res[now]=c;
ans=(ans+res[now])%mod;
}
last=next[cur][c];
}
}P;
char s[maxn];
int main()
{
scanf("%s",s);
int len=strlen(s);
po[1]=1;
for(int i=2;i<=len;i++)po[i]=(po[i-1]*10)%mod;
P.init();
for(int i=0;i<len;i++)
P.add(s[i]);
printf("%lld\n",ans);
}