bzoj 3676 回文串 manachar+hash
考虑每个回文串,它一定是它中心字母的最长回文串两侧去掉同样数量的字符后的一个子串。
所以我们可以用manachar求出每一位的回文半径,放到哈希表里并标记出它的下一个子串。
最后拓扑排序递推就行了。。。
这道题丧心病狂卡哈希。。。。wa了一屏。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#define bas 131
#define bs 31
#define p 1000000007
#define p2 986598521
#define ll long long
#define N 1200005
using namespace std;
char c[N],s[N*];
int hui[N],n;
ll hash[N],pw[N],hash2[N],pw2[N];
int head[],nxt[N],tot,len[N],size[N],zhi[N];
ll key[N],key2[N],nx[N],nx2[N];
void insert(ll x,ll xx,int l,ll z,int ss,ll ww)
{
int y=x%;
tot++;nxt[tot]=head[y];head[y]=++tot;len[tot]=l;key[tot]=x;nx[tot]=z;zhi[tot]=ss;key2[tot]=xx;nx2[tot]=ww;
return ;
}
int find(ll x,ll xx)
{
int y=x%;
for(int i=head[y];i;i=nxt[i])
{
if(key[i]==x&&key2[i]==xx)return i;
}
return ;
}
int head2[N],ver2[N],nxt2[N],tot2;
void add2(int x,int y)
{
tot2++;nxt2[tot2]=head2[x];head2[x]=tot2;ver2[tot2]=y;return ;
}
void manachar()
{
int mx=,id=;
for(int i=;i<=n;i++)
{
if(i>mx)
{
hui[i]=;
mx=i;id=i;
}
else
{
hui[i]=min(hui[id-(i-id)],mx-i+);
}
int l=i-hui[i],r=i+hui[i];
while(l!=&&r!=n+&&s[l]==s[r])
{
hui[i]++;
mx=i+hui[i]-;
id=i;
l--;r++;
}
int tmp=hui[i];
if(s[i+hui[i]-]=='#')tmp--;
if(tmp==)continue;
int pos2=tmp+i-,pos1=i-tmp+;
int lenn=(pos2-pos1)/+;
ll haha,haha2;
ll ha=(hash[pos2/]-(hash[pos1/-]*pw[lenn])%p+p)%p;
ll ha2=(hash2[pos2/]-(hash2[pos1/-]*pw2[lenn])%p2+p2)%p2;
if(pos2==pos1||pos2==pos1+)haha=,haha2=;
else haha=(hash[pos2/-]-(hash[pos1/]*pw[lenn-])%p+p)%p,haha2=(hash2[pos2/-]-(hash2[pos1/]*pw2[lenn-])%p2+p2)%p2;
int k=find(ha,ha2);
if(!k)insert(ha,ha2,lenn,haha,pos2/,haha2),size[tot]++;
else size[k]++;
}
}
queue<int>qu;
int ru[N];
ll ans;
void tupu()
{
for(int i=;i<=tot;i++)if(!ru[i])qu.push(i);
while(!qu.empty())
{
int tmp=qu.front();qu.pop();
ans=max(ans,(ll)size[tmp]*len[tmp]);
for(int i=head2[tmp];i;i=nxt2[i])
{
ru[ver2[i]]--;
size[ver2[i]]+=size[tmp];
if(!ru[ver2[i]])qu.push(ver2[i]);
}
}
}
int main()
{
scanf("%s",c+);
n=strlen(c+);
pw[]=;pw2[]=;
for(int i=;i<=n;i++)pw[i]=(pw[i-]*bas)%p;
for(int i=;i<=n;i++)pw2[i]=(pw2[i-]*bs)%p2;
for(int i=;i<=n;i++)hash[i]=(hash[i-]*bas+c[i]-'a'+)%p;
for(int i=;i<=n;i++)hash2[i]=(hash2[i-]*bs+c[i]-'a'+)%p2;
for(int i=;i<=n*+;i++)
{
if(i&)s[i]='#';
else s[i]=c[i/];
}
n=n*+;
manachar();
for(int i=;i<=tot;i++)
{
if(nx[i]==)continue;
int tmp=find(nx[i],nx2[i]);
if(tmp!=)add2(i,tmp),ru[tmp]++;
else
{
ll now,now2;
if(len[i]<=)now=,now2=;
else
{
now=(hash[zhi[i]-]-(hash[zhi[i]-len[i]+]*pw[len[i]-])%p+p)%p;
now2=(hash2[zhi[i]-]-(hash2[zhi[i]-len[i]+]*pw2[len[i]-])%p2+p2)%p2;
}
insert(nx[i],nx2[i],len[i]-,now,zhi[i]-,now2);
add2(i,tot);ru[tot]++;
}
}
tupu();
printf("%lld\n",ans);
return ;
}
bzoj 3676 回文串 manachar+hash的更多相关文章
- 回文树(回文自动机) - BZOJ 3676 回文串
BZOJ 3676 回文串 Problem's Link: http://www.lydsy.com/JudgeOnline/problem.php?id=3676 Mean: 略 analyse: ...
- BZOJ 3676 回文串
Description 考虑一个只包含小写拉丁字母的字符串\(s\).我们定义\(s\)的一个子串\(t\)的"出现值"为\(t\)在\(s\)中的出现次数乘以\(t\)的长度.请 ...
- BZOJ 3676 回文串(回文树)题解
题意: 一个回文的价值为长度 * 出现次数,问一个串中的子串的最大回文价值 思路: 回文树模板题,跑PAM,然后计算所有节点出现次数. 参考: 回文串问题的克星--Palindrome Tree(回文 ...
- BZOJ - 3676 回文串 (回文树)
https://vjudge.net/problem/HYSBZ-3676 题意 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s ...
- HYSBZ 3676 回文串 (回文树)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1680 Solved: 707 [Submit][Stat ...
- [CSP-S模拟测试]:回文串(hash+二分)
题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...
- BZOJ 2342 回文串-Manacher
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2342 思路:先跑一遍Manacher求出p[i]为每个位置为中心的回文半径,因为双倍回文串 ...
- BZOJ 2565 回文串-Manacher
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2565 题意:中文题 思路:定义L[i],R[i].表示以i为左端点/右端点时,最长回文串长 ...
- POWEROJ 2610 判断回文串 【HASH】
题目链接[https://www.oj.swust.edu.cn/problem/show/2610] 题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e ...
随机推荐
- java web学习总结(三十一) -------------------EL表达式
一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...
- string.empty , "" , null 以及性能的比较
一:这种结论,个人觉得仍然存疑 http://www.cnblogs.com/wangshuai901/archive/2012/05/06/2485657.html 1.null null 关 ...
- commit(), commitNow()和commitAllowingStateLoss()
关于FragmentTransaction的各种提交方法: commit(),commitAllowingStateLoss(),commitNow()和commitNowAllowingStateL ...
- Android面试题--事件处理
1.Handler 机制 Android 中主线程也叫 UI 线程,那么从名字上我们也知道主线程主要是用来创建.更新 UI 的,而其他耗时操作,比如网络访问,或者文件处理,多媒体处理等都需要在子线程中 ...
- c++宏定义命令
在程序开始以#开头的命令,他们是预编译命令.有三类预编译命令:宏定义命令.文件包含命令.条件编译命令:今天聊聊宏定义: 宏定义命令将一个标识符定义为一个字符串,源程序中的该标识符均以指定的字符串来代替 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- 一个高级的J2E工程师需要面对MySQL要有那些基本功夫呢<上>
1. MySQL的架构介绍1.1 MySQL简介: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不 ...
- Javascript——arguments的shift问题谈方法“借用”
今天本来运行了打算这样的方法 arguments.shift() (shift方法是删除数组的第一个元素,例如var arr=[1,2,3,4,5]执行var a=arr.shift();之后,a的值 ...
- Maven:jar 下载相关的问题
在使用Maven下载jar包时,会遇到一些问题,如何解决他们呢? 1.仓库里有jar 包,更新Maven时报仓库里找不到jar包的错误 这个问题,时常在版本有大的变动时出现.(例如:新增加了一些fea ...
- Tomcat 服务应用
转自:http://wiki.jikexueyuan.com/project/tomcat/windows-service.html Tomcat8 是一个服务应用,能使 Tomcat 8 以 Win ...