HDU - 5157 :Harry and magic string (回文树,求多少对不相交的回文串)
2024-10-18 11:20:09
Sample Input
aca
aaaa
Sample Output
3
15
题意: 多组输入,每次给定字符串S(|S|<1e5),求多少对不相交的回文串。
思路:可以用回文树求出以每个位置结尾的回文串数,那么累加得到前缀和; 倒着再做一遍得到每个位置为开头的回文串数,乘正向求出的前缀和即可。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=;
struct PAT
{
struct node{
int len,num,fail,son[];
}t[maxn];
int last,n,tot,s[maxn];
void init()
{
memset(t,,sizeof(t));
tot=last=; n=;
t[].len=; t[].len=-;
t[].fail=t[].fail=;
s[]=-;
}
int add(int c){
int p=last; s[++n]=c;
while(s[n]!=s[n--t[p].len]) p=t[p].fail;
if(!t[p].son[c]){
int v=++tot,k=t[p].fail;
while(s[n]!=s[n-t[k].len-]) k=t[k].fail;
t[v].fail=t[k].son[c];
t[v].len=t[p].len+;
t[v].num=t[t[v].fail].num+;
t[p].son[c]=v;
}
last=t[p].son[c];
return t[last].num;
}
}T;
ll ans,sum[maxn];char c[maxn];
int main()
{
while(~scanf("%s",c+)){
int N=strlen(c+);
T.init(); ans=;
rep(i,,N) sum[i]=sum[i-]+T.add(c[i]-'a');
T.init();
rep2(i,N,) ans+=sum[i-]*T.add(c[i]-'a');
printf("%lld\n",ans);
}
return ;
}
最新文章
- ios UI 适配布局相关文章
- 洛谷P1736 创意吃鱼法
- protected 和default的区别
- .NET Web开发总结(二)
- javascript之面向对象程序设计(对象和继承)
- Python环境搭建中解决C编译的问题
- Android源代码分析之Framework的MediaPlayer
- android平板Home键的监听
- Windows Phone开发(35):使用Express Blend绘图
- Swoole笔记(四)
- 【Hadoop】NameNode
- Javascript数组求和的方法总结 以及由斐波那契数列得到的启发
- 仿qq最新侧滑菜单
- High Availability手册(2): 架构
- Guess Number Game
- ROSETTA使用技巧随笔--relax使用
- 汇编 shr 逻辑右移指令,shl 逻辑左移指令,SAL 算术左移指令,SAR 算术右移指令
- Struts2 文件下载(中文处理方法以及控制下载文件名称和扩展名)
- POJ 2752 KMP中next数组的理解
- Android 压力测试工具Monkey