点我看题
题意:
  给出一个长度为N的字符串,要求输出一个长度为N的数组A, A[i]表示长度为i的good substring的数量
good substring 的定义是 该子串是回文串,且该子串的一半也是回文串。

解题思路:
  首先,要知道怎么判断一个回文串是一个goodsubstring。 这个很简单,哈希,马拉车都可以在O(n)预处理,O(1)时间内查询。
  那如何找出所有回文串呢,这个可以用回文树解决。 是回文树的基本应用。

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
const int MAXN = 300005 ;
const int N = 26 ;
const int MAX = MAXN;
char strs[MAX];
struct Palindromic_Tree {int next[MAXN][N] ;//next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成int fail[MAXN] ;//fail指针,失配后跳转到fail指针指向的节点int cnt[MAXN] ;int num[MAXN] ;int len[MAXN] ;//len[i]表示节点i表示的回文串的长度int S[MAXN] ;//存放添加的字符int last ;//指向上一个字符所在的节点,方便下一次addint n ;//字符数组指针int p ;//节点指针int endpos[MAXN];int newnode ( int l ) {//新建节点for ( int i = 0 ; i < N ; ++ i ) next[p][i] = 0 ;cnt[p] = 0 ;num[p] = 0 ;len[p] = l ;return p ++ ;}void init () {//初始化p = 0 ;newnode (  0 ) ;newnode ( -1 ) ;last = 0 ;n = 0 ;S[n] = -1 ;//开头放一个字符集中没有的字符,减少特判fail[0] = 1 ;}int get_fail ( int x ) {//和KMP一样,失配后找一个尽量最长的while ( S[n - len[x] - 1] != S[n] ) x = fail[x] ;return x ;}void add ( int c ,int pos) {c -= 'a' ;S[++ n] = c ;int cur = get_fail ( last ) ;//通过上一个回文串找这个回文串的匹配位置if ( !next[cur][c] ) {//如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串int now = newnode ( len[cur] + 2 ) ;//新建节点fail[now] = next[get_fail ( fail[cur] )][c] ;//和AC自动机一样建立fail指针,以便失配后跳转next[cur][c] = now ;num[now] = num[fail[now]] + 1 ;}last = next[cur][c] ;cnt[last] ++ ;endpos[last] = pos;}void slove(){for(int i=p-1;i>0;i--){//printf("cnt[%d]=cnt[%d]+cnt[%d]=%d\n",fail[i],fail[i],i,cnt[fail[i]]);cnt[fail[i]]+=cnt[i];}}
};
class HASH{
public:ULL base = 233;ULL p[2 * MAXN];ULL Hash[2 * MAXN];//u[x]=hashvalue(1,x);void init(char s[], int k)  //预处理主串的Hash前缀hash值和p的次方.{p[0] = 1;Hash[0] = 0;for (int i = 1; i <= k; i++) p[i] = p[i - 1] * base;for (int i = 1; i <= k; i++) {Hash[i] = Hash[i - 1] * base + (s[i] - 'a' + 1);}}ULL get(int l, int r)   //由公式得到hash[r-l]的值.{return Hash[r] - Hash[l - 1] * p[r - l + 1];}
};
HASH hash1,hash2;
Palindromic_Tree pam;
int ans[MAX];
bool check(int pos,int cntlen,int len){int R=pos,L=pos-cntlen+1;int R1=len-L+1,L1=len-R+1;//cout<<L<<","<<R<<"----"<<L1<<","<<R1<<endl;return (hash1.get(L,R)==hash2.get(L1,R1));
}
int main(){while(~scanf("%s",strs+1)){int len = strlen(strs+1);pam.init();for(int i=1;i<=len;i++){pam.add(strs[i],i);ans[i]=0;
//            cout<<"add:"<<pam.last<<",len:"<<pam.len[pam.last]<<endl;}hash1.init(strs,len);reverse(strs+1,strs+len+1);hash2.init(strs,len);pam.slove();for(int i=2;i<pam.p;i++){int cntlen = pam.len[i];//cout<<"i:"<<i<<",len:"<<pam.len[i]<<",num:"<<pam.cnt[i]<<",fail:"<<pam.fail[i]<<endl;int pos = pam.endpos[i];//cout<<L<<","<<R<<"----"<<L1<<","<<R1<<endl;if(check(pos-(cntlen/2),(cntlen+1)/2,len)){//cout<<"L:"<<L<<",R:"<<R<<mnc.check(L,mid)<<","<<mnc.check(mid|1,R)<<endl;ans[cntlen]+=pam.cnt[i];}}for(int i=1;i<=len;i++){if(i==1){printf("%d",ans[i]);}else{printf(" %d",ans[i]);}}puts("");}return 0;
}

HDU6599I Love Palindrome String 回文树+哈希相关推荐

  1. HDU - 6599 I Love Palindrome String (回文树+Manacher、回文树+hash)

    题目链接 题意 一个长度为3e5的字符串,求长度为iii的字符串满足字符是回文串而且字符串的前一半也是回文串的个数 思路 回文数求出所有的回文字符串,然后用Manacher或者Hash判断是否符合条件 ...

  2. 2019牛客暑期多校训练营(第六场)C - Palindrome Mouse (回文树dfs)

    题目链接 题意 一个字符串,求有多少对(S,T)(S,T)(S,T),满足S.TS.TS.T是回文串,S是T的子串S是T的子串S是T的子串 思路 题解还没看懂- 看大佬代码,好多在回文树上dfsdfs ...

  3. 【题解】HDU6599 I Love Palindrome String 回文自动机

    补一下多校里碰到的字符串题. 来源:2019 HDU Multi-University Training Contest 2 - 09 给定一个字符串S,对于每个i,输出有多少个子串s[l,r]满足以 ...

  4. HDU2019多校第二场 1009(HDU 6599) I Love Palindrome String(回文树(自动机)+manacher)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 解题思路: 回文自动机求每个本质不同的子串出现的次数,同时记录每个节点i代表的回文串第一次出现的 ...

  5. 回文串问题的克星——Palindrome Tree(回文树)/Palindrome Automaton(回文自动机)学习小记

    前言 最近B组有一道我不会的题,赶紧学习. 简介 我们知道,Manacher算法可以在 O(n) O ( n ) O(n)的时间内求出以每个位置为中心的最长回文串(虽然我昨天还不知道Manacher算 ...

  6. 2018 ICPC 南京 M. Mediocre String Problem(ExKMP + Manacher / ExKMP+回文树)

    2018 ICPC 南京 全文见:https://blog.csdn.net/qq_43461168/article/details/112796538 M. Mediocre String Prob ...

  7. 19 ICPC 徐州网络赛 G. Colorful String(回文树)

    传送门 题意:求出给出的字符串中所有回文字符串的不同字符和. 思路:回文树+二进制表示字符 (例如 a==1<<0,b==1<<1,c==1<<2,d==1< ...

  8. 回文树(回文自动机) - URAL 1960 Palindromes and Super Abilities

     Palindromes and Super Abilities Problem's Link:  http://acm.timus.ru/problem.aspx?space=1&num=1 ...

  9. HDU 5157(回文树)

    传送门 题面: Harry got a string T, he wanted to know the number of T's disjoint palindrome substring pair ...

最新文章

  1. Java日期时间使用总结
  2. Linux学习笔记之三
  3. 依赖注入 这样的坑游戏编程要谨慎
  4. 想要AI优先?数据优先才行
  5. var _ biz.GreeterRepo = (*greeterRepo)(nil)的总结
  6. HBase 基本入门篇
  7. matlab rand函数
  8. Netty 整合 MessagePack 序列化框架 + LengthFieldBasedFrameDecoder 自定义解码器
  9. excel绘制直方图
  10. 使用android studio设置签名信息
  11. 计算机二级文档技巧,计算机二级选择题技巧
  12. 滴滴出行DIDI美国IPO上市路演PPT:Roadshow Presentation
  13. Vue项目:IE11中地址栏直接改变路由页面不跳转bug
  14. 静态库与共享库制作,及区别
  15. 关于 NB-IoT NM1 模组 - FAQ
  16. mysql教程 check_Check
  17. oracle环境配置全过程
  18. 创新型中小企业认定条件
  19. 大搜车:云上多地域高可用消息系统的构建
  20. 黑马程序员 java中关于异常的学习日志

热门文章

  1. OCR 图片文字识别图解教程
  2. 机会总是给有准备的人
  3. 如何将chatgpt融入搜索引擎
  4. 中文自然语言处理,繁体转简体(下载langconv)
  5. java 如何循环执行一个对象_如何跟相亲对象聊微信?四个技巧一用一个准
  6. Android 天气APP(四)搭建MVP框架与使用
  7. PC-DMIS 2019检测夹具中与基准面不垂直定位销的方法
  8. 【Linux】Linux入门学习之常用命令一
  9. 数据挖掘r语言和python知乎_Hellobi Live |R语言爬虫实战案例分享:网易云课堂、知乎live、今日头条、B站视频...
  10. FLASH软件测试培训,Flash基础知识测试题(最新整理)