2019 Multi-University Training Contest 2 I.I Love Palindrome String(回文自动机+字符串hash)
∙ r−l+1 equals to i.
∙ The substring slsl+1...sr is a palindrome string.
∙ slsl+1...s⌊(l+r)/2⌋ is a palindrome string too.
|S| denotes the length of string S.
A palindrome string is a sequence of characters which reads the same backward as forward, such as madam or racecar or abba.
Each case starts with a line containing a string S(1≤|S|≤3×105) containing only lowercase English letters.
It is guaranteed that the sum of |S| in all test cases is no larger than 4×106.
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
const int inf = 0x3f3f3f3f;
const int N = 4e5+7;
const ll mod = 998244353;
using namespace std;
ull hash1=233;
ull ha[N],pp[N];
ull getha(int l,int r){
if(l==0) return ha[r];
return ha[r]-ha[l-1]*pp[r-l+1];
}
struct Palindromic_Tree{
int next[N][30]; //节点之间连边
int fail[N]; //适配指针 表示当前回文串的最长回文后缀
int len[N]; //当前回文串的长度
int cnt[N]; //回文串的个数
int id[N]; //回文串的右端点
int S[N];
int last,n,p;
int newnode(int l){//新建节点
for(int i=0;i<26;i++) next[p][i]=0;//新建的节点为p,先消除它的子节点
cnt[p]=0;
len[p]=l;
return p++;//勿打成++p,因为此节点为p,我们应返回p
}
void init(){
last=n=p=0;
newnode(0); newnode(-1);
S[0]=-1; fail[0]=1;
}
int get_fail(int x){
while(S[n-len[x]-1]!=S[n]) x=fail[x];
return x;
}
void add(int c){
c-='a';
S[++n]=c;
int po=get_fail(last);
if(!next[po][c]){
int now=newnode(len[po]+2);
fail[now]=next[get_fail(fail[po])][c];
next[po][c]=now;
}
last=next[po][c];
cnt[last]++;
id[last]=n;
}
void count(){
for(int i=p-1;i>=0;i--)
cnt[fail[i]]+=cnt[i];
}
}pat;
ll ans[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
pp[0]=1;
for(int i=1;i<N;i++) {
pp[i]=hash1*pp[i-1];
}
string s;
while(cin>>s){
memset(ans,0,sizeof(ans));
pat.init();
int len=s.length();
for(int i=0;i<len;i++){
pat.add(s[i]);
}
ha[0]=s[0];
for(int i=1;i<len;i++)
ha[i]=ha[i-1]*hash1+s[i];
pat.count();
for(int i=2;i<pat.p;i++){
int l=pat.id[i]-pat.len[i];
int r=pat.id[i]-1;
int mid=(l+r)>>1;
if((r-l+1)&1){
if(getha(l,mid)==getha(mid,r)){
ans[pat.len[i]]+=pat.cnt[i];
}
}else{
if(getha(l,mid)==getha(mid+1,r)){
ans[pat.len[i]]+=pat.cnt[i];
}
}
}
for(int i=1;i<=len;i++){
if(i==1) cout<<ans[i];
else cout<<" "<<ans[i];
}
cout<<endl;
}
return 0;
}
2019 Multi-University Training Contest 2 I.I Love Palindrome String(回文自动机+字符串hash)的更多相关文章
- [2019杭电多校第二场][hdu6599]I Love Palindrome String(回文自动机&&hash)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 题目大意为求字符串S有多少个子串S[l,r]满足回文串的定义,并且S[l,(l+r)/2]也满足 ...
- 2019牛客暑期多校训练营(第六场)C - Palindrome Mouse (回文自动机)
https://ac.nowcoder.com/acm/contest/886/C 题意: 给出一个串A , 集合S里面为A串的回文字串 , 现在在集合S里面找出多少对(a,b),b为a的字串 分析: ...
- 2015 Multi-University Training Contest 6 hdu 5362 Just A String
Just A String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- 2019 Nowcoder Multi-University Training Contest 4 E Explorer
线段树分治. 把size看成时间,相当于时间 $l$ 加入这条边,时间 $r+1$ 删除这条边. 注意把左右端点的关系. #include <bits/stdc++.h> ; int X[ ...
- 2019 Nowcoder Multi-University Training Contest 1 H-XOR
由于每个元素贡献是线性的,那么等价于求每个元素出现在多少个异或和为$0$的子集内.因为是任意元素可以去异或,那么自然想到线性基.先对整个集合A求一遍线性基,设为$R$,假设$R$中元素个数为$r$,那 ...
- 2019 Multi-University Training Contest 2 - 1009 - 回文自动机
http://acm.hdu.edu.cn/showproblem.php?pid=6599 有好几种实现方式,首先都是用回文自动机统计好回文串的个数. 记得把每个节点的cnt加到他的fail上,因为 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 G. Colorful String 回文树
签到提: 题意:求出每一个回文串的贡献 (贡献的计算就是回文串不同字符的个数) 题解: 用回文树直接暴力即可 回文树开一个数组cost[ ][26] 和val[ ] 数组: val[i]表示回文树上节 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 G Colorful String(回文自动机+dfs)
这题建立一棵回文树,然后用dfs搜索答案,但是有一点需要注意,就是打vis的标记时,如果标记为1,那么在好几个节点都对同一个字符i打过标记,此时的搜索从字符i点回溯,回到它的父亲节点,搜索其它的字符, ...
- 回文自动机 + DFS --- The 2014 ACM-ICPC Asia Xi’an Regional Contest Problem G.The Problem to Slow Down You
The Problem to Slow Down You Problem's Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.actio ...
随机推荐
- #3使用html+css+js制作网页 番外篇 使用python flask 框架 (I)
#3使用html+css+js制作网页 番外篇 使用python flask 框架(I 第一部) 0. 本系列教程 1. 准备 a.python b. flask c. flask 环境安装 d. f ...
- STP、PVST、MST协议
• STP:生成树协议 ○ 阻止环形链路的广播风暴 • PVST:VLAN生成树 ○ 是STP的进阶版不仅能阻止广播风暴,还可以做到基于VLAN进行流量均衡. ...
- paramunittest参数化测试基础
samples: import paramunittestimport unittest@paramunittest.parametrized( (10,20), (30,40), # (100,20 ...
- kubernets之pod的标签
一 如何查看pod 的日志 1 通过执行命令查看日志信息 kubectl logs pod_name 二 创建带有标签的pod,一个范例的pod创建yaml文件如下所示 2.1 创建带有 ...
- leetcode 470. 用 Rand7() 实现 Rand10() (数学,优化策略)
题目链接 https://leetcode-cn.com/problems/implement-rand10-using-rand7/ 题意: 给定一个rand7()的生成器,求解如何产生一个rand ...
- MyBatis初级实战之四:druid多数据源
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- oracle 释放表空间到OS(resize)
1.查看表空间里面的对象 SELECT OWNER AS OWNER, SEGMENT_NAME AS SEGMENT_NAME, SEGMENT_TYPE AS SEGMENT_TYPE, SUM ...
- vagrant up报错【io.rb:32:in `encode': "\x95" followed by "\"" on GBK (Encoding::InvalidByteSequenceError)】
vagrant up报错[io.rb:32:in `encode': "\x95" followed by """ on GBK (Encoding: ...
- 视频画面中实现人脸遮挡教程 - 基于 TensorFlow 实现
在进行视频通话时,我们往往需要对画面进行一些实时分析,例如识别画面里的人.车.动物等等.这节里我们将使用时信魔方的人脸监视模块实现人脸被手部遮挡的检测,如下图所示效果: 预备知识 时信魔方的客户端使用 ...
- 4、python+selenium实现12306模拟登录
简介: 这里是利用了selenium+图片识别验证,来实现12306的模拟登录,中间也参考了好几个项目,实现了这个小demo,中间也遇到了很多的坑,主要难点在于图片识别和滑动验证这两个方面,图片识别是 ...