3676: [Apio2014]回文串

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2343  Solved: 1031

Description

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 
大出现值。

Input

输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。

Output

输出一个整数,为逝查回文子串的最大出现值。

Sample Input

【样例输入l】
abacaba

【样例输入2]
www

Sample Output

【样例输出l】
7

【样例输出2]
4

HINT

一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。

在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中:

● a出现4次,其出现值为4:1:1=4

● b出现2次,其出现值为2:1:1=2

● c出现1次,其出现值为l:1:l=l

● aba出现2次,其出现值为2:1:3=6

● aca出现1次,其出现值为1=1:3=3

●bacab出现1次,其出现值为1:1:5=5

● abacaba出现1次,其出现值为1:1:7=7

故最大回文子串出现值为7。

【数据规模与评分】

数据满足1≤字符串长度≤300000。

Source

【分析】

  听说回文自动机可以秒掉这题,以后再学吧。

  用串建SAM,然后求出right数组。

  manacher告诉我们,本质不同的回文串最多n个,只有在mx变的时候可能增加一个回文串。

  用manacher求出所有本质不同的回文串,然后在SAM上问。

  那就是问[L,R]这个区间的子串出现了多少次【感觉这个用后缀数组的话是nlogn^2的

  从SAM的pre边相当于AC自动机上的fail,形成一棵树,pre树上倍增即可。

  就是从POS[R]开始跳,当他代表的子串的长度大于r-l+1,即可计入答案,当然子串长度越小越好(更有可能出现最多次)

  【记得拓扑序

  【啊。。。卡空间。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 301000
#define LL long long // int mymax(int x,int y) {return x>y?x:y;}
LL mymax(LL x,LL y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;} LL ans=; struct node
{
int pre,step,son[],rt;
}t[*Maxn];int last,tot;
int v[*Maxn],q[*Maxn],pos[*Maxn]; int ff[*Maxn][];
void get_f()
{
for(int i=;i<=tot;i++) ff[i][]=t[i].pre;
for(int i=;i<=tot;i++)
{
int nw=q[i];
for(int j=;j<=;j++)
ff[nw][j]=ff[ff[nw][j-]][j-];
}
} int now;
struct sam
{
void extend(int k)
{
int np=++tot,p=last;
t[np].step=t[last].step+;
t[np].rt=;pos[++now]=np;
while(p&&!t[p].son[k])
{
t[p].son[k]=np;
p=t[p].pre;
}
if(!p) t[np].pre=;
else
{
int q=t[p].son[k];
if(t[q].step==t[p].step+) t[np].pre=q;
else
{
int nq=++tot;
memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
t[nq].step=t[p].step+;
t[nq].pre=t[q].pre;
t[q].pre=t[np].pre=nq;
while(p&&t[p].son[k]==q)
{
t[p].son[k]=nq;
p=t[p].pre;
}
}
}
last=np;
}
void init()
{
memset(v,,sizeof(v));
for(int i=;i<=tot;i++) v[t[i].step]++;
for(int i=;i<=tot;i++) v[i]+=v[i-];
for(int i=tot;i>=;i--) q[v[t[i].step]--]=i; for(int i=tot;i>=;i--)
{
int nw=q[i];
t[t[nw].pre].rt+=t[nw].rt;
}
}
void ffind(int l,int r)
{
l=l/+;r=(r+)/;
int x=pos[r];
for(int i=;i>=;i--)
{
if(t[ff[x][i]].step>=r-l+) x=ff[x][i];
}
ans=mymax(ans,1LL*(r-l+)*t[x].rt);
}
}sam; char s[Maxn];
// int a[2*Maxn],p[2*Maxn]; void manacher(int l)
{
v[]=;
for(int i=;i<l;i++) v[*i+]=s[i]-'a'+,v[*i+]=;
v[*l+]=;
l=*l;
int mx=,id=;
for(int i=;i<=l;i++)
{
if(i<mx) q[i]=mymin(mx-i+,q[*id-i]);
else q[i]=;
while(v[i+q[i]]==v[i-q[i]]&&i-q[i]>=)
{
q[i]++;
sam.ffind(i-q[i]+,i+q[i]-);
}
if(i+q[i]->mx) mx=i+q[i]-,id=i;
}
} int main()
{
scanf("%s",s);
int l=strlen(s);
last=tot=;now=;
for(int i=;i<l;i++) sam.extend(s[i]-'a'+);
sam.init();
get_f();
manacher(l);
printf("%lld\n",ans);
return ;
}

2017-04-17 16:54:09

【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)的更多相关文章

  1. BZOJ3676:[APIO2014]回文串(SAM,Manacher)

    Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...

  2. BZOJ3676 APIO2014回文串(manacher+后缀自动机)

    由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计.可以发现manacher时若右端点移动则找到了一个新回文串.注意这样会漏掉串长为1的情况,特判一下. 现在问 ...

  3. bzoj 3676 [Apio2014]回文串(Manacher+SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3676 [题意] 给定一个字符串,定义一个串的权值为长度*出现次数,求最大权的回文子串. ...

  4. 【BZOJ 3676】[Apio2014]回文串

    [链接] 链接 [题意] 给你一个字符串s. 定义一个子串的出现值为它出现的次数*字符串的长度. 让你求里面的回文子串的最大出现值 |s|<=3e5 [题解] 马拉车算法里面. 只有在回文往外扩 ...

  5. bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增

    bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...

  6. BZOJ 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2013  Solved: 863[Submit][Status ...

  7. bzoj 3676: [Apio2014]回文串 回文自动机

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 844  Solved: 331[Submit][Status] ...

  8. 3676: [Apio2014]回文串

    3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1740 Solved: 744 [Submit][Status ...

  9. 3676: [Apio2014]回文串 求回文串长度与出现次数的最大值

    「BZOJ3676」[Apio2014] 回文串   Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所 ...

随机推荐

  1. matlab实现cart(回归分类树)

    作为机器学习的小白和matlab的小白自己参照 python的 <机器学习实战> 写了一下分类回归树,这里记录一下. 关于决策树的基础概念就不过多介绍了,至于是分类还是回归..我说不清楚. ...

  2. 2017ACM暑期多校联合训练 - Team 2 1011 HDU 6055 Regular polygon (数学规律)

    题目链接 **Problem Description On a two-dimensional plane, give you n integer points. Your task is to fi ...

  3. react 修改state某一属性值

    1.state // 筛选框相关数据 searchSelect: { term: { value: '学期', key: '', options: [] }, type_of_personnel: { ...

  4. bzoj 1143 二分图最大独立集

    我们可以将一个点拆成两个点x,y,那么如果存在一条i->j的路径,我们就连接xi,yj,那么答案就是n-最大匹配数. 因为i->j所以对于i与j只能选一个,那么我们只需要求出来二分图的最大 ...

  5. React 16 源码瞎几把解读 【前戏】 为啥组件外面非得包个标签?

    〇.看前准备 1.自行clone react最新代码 2.自行搭建一个能跑react的test项目 一.看表面:那些插件 如何解析JSX 有如下一段代码: // ---- hearder.jsx 组件 ...

  6. ProxySQL(MGR)部署故障:'sys.gr_member_routing_candidate_status' doesn't exist

    ProxySQL(MGR) 故障排查: 故障现象:runtime_mysql_servers节点状态offline_hostgroup(本案例为15) 日志关键信息: [WARNING] Group ...

  7. js日期工具

    /** * 日期工具类 */ define(function(require, exports, module) { var constants = require("constants&q ...

  8. 关于text-decoration无法清除继承的问题

    因为text-decoration的值可以叠加,所以即使设置了none,浏览器也是看成是叠加,而不是清除的意思.

  9. 016 sleep,wait,yield,join区别

    1.线程通常有五种状态,创建,就绪,运行.阻塞和死亡状态.2.阻塞的情况又分为三种:(1).等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中.进入 ...

  10. 如何使用curl命令指定ip访问url

    有时我们需要测试一个url,但域名并没解析,这时为了一个简单的测试而写host或去做域名解析,显然这并不高效,而有些域名甚至是正式的域名,因此我们可有使用curl命令进行测试 方法一 curl url ...