Hihocoder #1602 : 本质不同的回文子串的数量 manacher + BKDRhash
#1602 : 本质不同的回文子串的数量
描述
给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串?
注意如果两个位置不同的子串满足长度相同且对应字符也都相同,则认为这两个子串本质上是相同的。
输入
一个只包含小写字母的字符串S。
对于30%的数据,S长度不超过100。
对于60%的数据,S长度不超过1000。
对于100%的数据,S长度不超过800000。
输出
回文子串的数量
- 样例输入
-
abbab
- 样例输出
5
- 题解:
- 跑manacher的时候 hash标记即可
#include <bits/stdc++.h>
inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}
using namespace std; const long long INF = 1e14;
const int N = 1e6 + ; unsigned long long P = 10000019ULL;
unsigned long long sqr[N],has[N]; //BKDRHash,最优的字符串hash算法。hash一开始是等于0的
const int seed = ; // 31 131 1313 13131 131313 etc..
const int maxn = +;
char str[maxn];
unsigned long long sumHash[maxn]; //前缀hash值
const int MOD = ;
struct StringHash
{
int first[MOD+],num;
unsigned long long EdgeNum[maxn]; // 表明第i条边放的数字(就是sumHash那个数字)
int next[maxn],close[maxn]; //close[i]表示与第i条边所放权值相同的开始的最大位置
//就比如baba,现在枚举长度是2,开始的时候ba,close[1] = 1;表明"ba"开始最大位置是从1开始
//然后枚举到下一个ba的时候,close[1]就要变成3了,开始位置从3开始了
void init ()
{
num = ; memset (first,,sizeof first);
return ;
}
int insert (unsigned long long val,int id) //id是用来改变close[]的
{
int u = val % MOD;
for (int i = first[u]; i ; i = next[i]) //存在边不代表出现过,出现过要用val判断,val才是唯一的,边还是压缩后(%MOD)的呢
{
if (val == EdgeNum[i]) //出现过了
{
int t = close[i]; close[i] = id;//更新最大位置
return t;
}
}
++num; //没出现过的话,就加入图吧
EdgeNum[num] = val; // 这个才是精确的
close[num] = id;
next[num] = first[u];
first[u] = num;
return ;//没出现过
}
}H; char a[N];
int ans = ;
map<unsigned long long, int> mp;
void gao(int i,int j) {
unsigned long long now = has[j] - has[i-] * sqr[j-i+];
if(!H.insert(now,)) ++ans,mp[now]++;
}
int r[N];
int main() {
scanf("%s",a+);
int n = strlen(a+);
sqr[] = ;for(int i = ; i <= n; ++i) sqr[i] = sqr[i-] * P;
for(int i = ; i <= n; ++i) has[i] = has[i-] * P + a[i];
int x = , p = ;
for(int i = ; i <= n; ++i) {
int j = ;
gao(i,i);
if(p > i) j = min(r[*x-i],p-i);
while(i + j + <= n&& a[i+j+] == a[i-j-])
{
gao(i-j-,i+j+);
j++;
}
r[i] = j;
if(i+j > p) {
p = i + j;
x = i;
}
}
H.init();
x = ,p = ;
for(int i = ; i <= n; ++i) {
int j = ;
if(p > i) j = min(r[*x-i],p-i+);
while(i+j<=n && a[i+j] == a[i-j-]) {
gao(i-j-,i+j);
++j;
}
r[i] = j;
if(i+j- > p) {
p = i+j-;
x = i;
}
}
printf("%d\n",ans);
return ;
}
Hihocoder #1602 : 本质不同的回文子串的数量 manacher + BKDRhash的更多相关文章
- hiho1602本质不同的回文子串的数量
给定一个字符串S,请统计S的所有子串中,有多少个本质不同的回文字符串? 注意如果两个位置不同的子串满足长度相同且对应字符也都相同,则认为这两个子串本质上是相同的. Input 一个只包含小写字母的字符 ...
- #1589 : 回文子串的数量(Manacher)
#1589 : 回文子串的数量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,请统计S的所有|S| * (|S| + 1) / 2个子串中(首尾位置不 ...
- 【HIHOCODER 1589】回文子串的数量(Manacher)
描述 给定一个字符串S,请统计S的所有|S| * (|S| + 1) / 2个子串中(首尾位置不同就算作不同的子串),有多少个是回文字符串? 输入 一个只包含小写字母的字符串S. 对于30%的数据,S ...
- 1089 最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa ...
- 51Nod 1089:最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaa ...
- 51NOD 1088 最长回文子串&1089 最长回文子串 V2(Manacher算法)
回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. Input 输入Str(Str的长度 <= 1000(第二题要 ...
- [51Nod1089] 最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 回文串是指aba.abba.cccbccc.aaaa这种左右对称 ...
- hdu5371 最长回文子串变形(Manacher算法)
pid=5371">http://acm.hdu.edu.cn/showproblem.php? pid=5371 Problem Description Hotaru Ichijou ...
- 【回文字符串】 最长回文子串O(N) Manacher算法
原理讲的清晰:Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 注意: ①动态生命P[]和newStr数组后,不要忘记delete[] //其实这是基本的编码习惯 ②最终 ...
随机推荐
- hdu 4530(数学)
小Q系列故事——大笨钟 Time Limit: 600/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total S ...
- python 编码问题之终极解决
结合之前遇到的坑以及下面贴的这篇文章, 总结几种python乱码解决方案,如果遇到乱码,不妨尝试一下? 1,必备 #encoding=utf-8 2, python编程环境编码 import sys ...
- IntelliJ IDEA安装MongoDB的的数据操作插件
说明:只能说效果一般,没有Robo 3T那么好用. 参考: https://intellij-support.jetbrains.com/hc/en-us/community/posts/206635 ...
- Beginning Auto Layout Tutorial in iOS 7: Part 6
Gallery example 屏幕有四个分开的相同的矩形,每个矩形有一个label和一个image view.创建一个Gallery的项目.在Main.storyboard中,拖拉一个view大小为 ...
- EV根证书
Extended Validation SSL Certificates翻译为扩展验证型服务器证书(EV 服务器证书 或 EV SSL证书),申请该证书需要经过最彻底的身份验证,确保证书持有组织的真实 ...
- 【温故知新】——原生js中常用的四种循环方式
一.引言 本文主要是利用一个例子,讲一下原生js中常用的四种循环方式的使用与区别: 实现效果: 在网页中弹出框输入0 网页输出“欢迎下次光临” 在网页中弹出框输入1 网页输出“查询中……” 在 ...
- centos DHCP
yum install dhcp cat /usr/share/doc/dhcp-4.2.5/dhcpd.conf.example > /etc/dhcp/dhcpd.conf vim /etc ...
- 微信小程序 - 时间戳转时间
获取当前时间:十位unix时间戳 var timestamps = Math.round(new Date().getTime() / 1000).toString(); 时间戳转时间(官方自带) 使 ...
- jquery相冊图片来回选择
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <script sr ...
- 如何删除mysql 主键索引
如果一个主键是自增长的,不能直接删除该列的主键索引, 应当先取消自增长,再删除主键特性 alter table 表名 drop primary key; [如果这个主键是自增的,先取消自增长.] ...