HDU6599 I Love Palindrome String(PAM)
链接
题意:
首先定义好的串:自身是回文串,且前一半也是回文串。前一半的定义为[l,(l+r)/2]除号为整除
给出一个字符串,求各种长度的好的串分别有几个
思路:
利用回文树求得各种不同本质的回文串的数量及长度,同时记录一下每种本质的回文串的一个右端点。根据右端点和长度可以容易地知道某种本质的回文串长什么样子,本质相同的回文串是一样的,右端点随便取一个就好了。如果一开始就对整个字符串跑一边马拉车,在判断一个回文串的前一半是不是回文串就可以O1的检查了。
检查前一半:我的马拉车板子中字符的下标是2×(原串中下标)+2,不同板子会有所不同
奇数长度回文串:aba,在马拉车中为#a#b#a#,直接取马拉车的最长回文半径数组中下标是中间字符对应的那个。
偶数长度回文串:abba,在马拉车中为#a#b#b#a#,这时取的是中间‘#’对应的最长回文半径。
参考代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 300005 ;
const int N = 26 ;char ss[MAXN];
char tmp[MAXN<<2];
int p[MAXN<<2];void manacher(char *s,int len){tmp[len*2+2]='$';tmp[len*2+1]='#';for(int i=len-1;i>=0;--i){tmp[i+i+2]=s[i];tmp[i+i+1]='#';}tmp[0]='*';int k=1,maxlen=0;for(int i=2;i<len+len+1;++i){int maxr=k+p[k]-1;p[i]=min(p[2*k-i],max(maxr-i+1,1));while(tmp[i-p[i]] == tmp[i+p[i]])++p[i];if(i+p[i]>k+p[k])k=i;if(p[i]>maxlen)maxlen=p[i];}
}bool judge(int l,int r){//printf("%d %d\n",l,r);int mid=(l+r)>>1;int lmid=(mid+l)>>1;int len=mid-l+1;//根据前一半的长度的奇偶性分别判断if(len&1){return p[2*lmid+2]-1>=len;//取中间字符}else{return p[2*lmid+3]-1>=len;//取中间‘#’}
}struct Palindromic_Tree {int next[MAXN][N] ;int fail[MAXN] ;int cnt[MAXN] ;int num[MAXN] ;int len[MAXN] ;int S[MAXN] ;int last ;int n ;int p ;int pos[MAXN];//记录不同本质回文串的一个右端点int ret[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 ;memset(ret, 0,sizeof(ret));}int get_fail ( int x ) {//和KMP一样,失配后找一个尽量最长的while ( S[n - len[x] - 1] != S[n] ) x = fail[x] ;return x ;}void add ( int c ) {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] ++ ;pos[last]=n;//pos随便记录下就好了,怎么简单怎么来}void count () {for ( int i = p - 1 ; i >= 0 ; -- i ) cnt[fail[i]] += cnt[i] ;//父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!for(int i=2;i<p;i++){if (judge(pos[i]-len[i],pos[i]-1)){ret[len[i]]+=cnt[i];}}}
}pt ;int main(){while (~scanf("%s",ss)){int len=strlen(ss);manacher(ss,len);pt.init();for(int i=0;i<len;i++){pt.add(ss[i]);}int ans=0;pt.count();for(int i=1;i<=len;i++){printf("%d%c",pt.ret[i],i==len?'\n':' ');}}return 0;
}
HDU6599 I Love Palindrome String(PAM)相关推荐
- HDU-6599 I Love Palindrome String(回文自动机+字符串hash)
题目链接 题意:给定一个字符串\(|S|\le 3\times 10^5\) 对于每个 \(i\in [1,|S|]\) 求有多少子串\(s_ls_{l+1}\cdots s_r\)满足下面条件 \( ...
- HDU-6599 I Love Palindrome String 杭电第二次多校赛(Manacher+回文自动机)
HDU-6599 I Love Palindrome String 杭电第二次多校赛(Manacher+回文自动机) 我的博客:https://acmerszq.cn 原题链接:http://acm. ...
- 2019暑期杭电多校HDU6599 I Love Palindrome String
2019杭电多校HDU6599 I Love Palindrome String 题目链接 I Love Palindrome String Time Limit: 4000/2000 MS (Jav ...
- LeetCode刷题记录10——434. Number of Segments in a String(easy)
LeetCode刷题记录10--434. Number of Segments in a String(easy) 目录 LeetCode刷题记录9--434. Number of Segments ...
- Swift2.0 中的String(一):常用属性
字符串算是平常用的比较多.花样也比较多的一个类型,昨天有空把相关的一些常用操作都写了一遍,总结出来.其实iOS里面的字符串更复杂,还有NSString系列等等,那些API太多将来需要用的时候再慢慢学. ...
- python映射类型list_python中标准数据类型:数字 string(字符串) list(列表) tuple(元组) dict(字典) sets(集合)共同点和区别:...
python中string.list.tuple.dict.sets共同点: 1.都是可迭代对象 python中string.list.tuple.sets共同点: 1.都是有序,支持索引 2.支持切 ...
- 中国体力活动监测器(PAM)市场趋势报告、技术动态创新及市场预测
体力活动监测器(PAM)市场的企业竞争态势 该报告涉及的主要国际市场参与者有Polar.Fitbit.Garmin.Omsignal.Withings.CamNtech.Adidas.iHealth. ...
- C++基础::string(三)
C++基础::string C++基础::string(二) 在单个字符的查找上,find 和 find_\first_of()是等价的 1. basename 和扩展名(extension)的获得 ...
- Java源码阅读之String(4)
Java源码阅读之String(4) 这一篇博客主要阅读String类的查找和替换相关的方法. /**查询当前对象的哈希码,如果当前对象没有计算过哈希码*则计算当前对象的哈希码并赋值给当前对象的has ...
最新文章
- 福利丨吴恩达机器学习新书免费领!
- centos 网卡配置(入门级)
- python作业网站_python大作业
- SCOM 2012知识分享-21:无代理管理
- 【python笔记】python模块 datatime模块
- R3 data related to category and hierarchy mapping logic in CRM
- oracle中orand使用,Postgres兼容Oracle研究——orafce调研
- iPhone 播放音频声音文件
- Mybatis一二级缓存的理解
- 计算机round是什么函数,round函数
- Python学习之表的数据类型
- 如何发布ArcGIS Server离线地图(google 瓦片)
- 令你的网站获得任意Google PR值的方法!
- 阿里云对象存储OSS
- 动态显示姓名--汇编语言版
- 弹出visual studio 实时调试器解决
- linux中tac的用法,如何在Linux中使用“cat”和“tac”命令与示例
- 农村姑娘误加了一个博士群,结果...
- mysql 设置 utc_关于时间:MySQL应该将其时区设置为UTC吗?
- 多线程学习--案例-子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次