关闭

bzoj 2565: 最长双回文串 manacher

55人阅读 评论(0) 收藏 举报
分类:

题目链接


【想说的话】

没有..


【题解】

肯定是先跑一遍manacher

然后就想找到对于每个字符,它作为一个回文串的起点和终点时,回文串最长能为多少

这时候我们发现当一个字符作为终点时,最长的回文串的对称中心一定是最靠前越好

那么我们就像是跑manacher时,从前往后扫,维护一个最右端点,如果找到了右端点大于最右端点的,就暴力地把这一段都计算下

假设我们目前扫到的对称中心为i,i+r[i]大于maxr了,那么就从maxr+1扫到i+r[i],假设扫到的是j,那么以它为终点的回文串最长为j-i+1


找以一个字符为起点的最长回文串就反过来扫一遍就好了


【代码】

#include<bits/stdc++.h>

using namespace std;

char c[100010];
char s[200020];
int r[200020],Max[200020],ans1[200020],ans2[200020];
int n;

void manacher(){
	int mr=0,num,len=strlen(c);
	r[0]=1;
	for(int i=0; i<len; i++)s[n++]='#',s[n++]=c[i];
	s[n++]='#';
	for(int i=0; i<n; i++){
		if(mr>i)r[i]=min(r[2*num-i],mr-i+1);
		while(i-r[i]>=0 && i+r[i]<n && s[i+r[i]]==s[i-r[i]])r[i]++;
		if(r[i]+i-1>mr)mr=r[i]+i-1,num=i;
	}
}

int main(){
	scanf("%s",c);
	manacher();
	int last=0;
	for(int i=0; i<n; i++){
		if(i+r[i]-1>last){
			for(int j=last+1; j<i+r[i]; j++)if(s[j]!='#')ans1[j]=j-i+1;
			last=i+r[i]-1;
		}
	}
	last=n;
	for(int i=n-1; i>=0; i--){
		if(i-r[i]+1<last){
			for(int j=last-1; j>i-r[i]; j--)if(s[j]!='#')ans2[j]=i-j+1;
			last=i-r[i]+1;
		}
	}
	int ans=0;
	for(int i=1; i<n; i++)if(s[i]!='#')ans=max(ans,ans1[i]+ans2[i+2]);
	printf("%d\n",ans);
	
	return 0;
}


0
0
查看评论

【bzoj2565】最长双回文串 manacher

刚开始读错题了,以为整个串也要是回文串,后来发现是两个回文串拼起来就好了,那么就先插入‘#’,然后算出l[i]表示以i为结尾的最左的回文串的中心,这个随便算一下就好了,然后枚举每一个‘#’当做断点,然后更新答案。 #include #include #include #include #i...
  • u012288458
  • u012288458
  • 2015-11-24 13:06
  • 907

BZOJ[2565]最长双回文串 Manacher

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=2565题目要求找由两个回文串拼一起最长的串 只寻找一个回文串Manacher就可以了 如果两个拼在一起,则在Manacher后,对于每个点i,统计是哪个点最先向右/左拓展到i 可以发现,用...
  • WADuan2
  • WADuan2
  • 2017-12-22 20:31
  • 67

BZOJ 2565 最长双回文串 Manacher

题目大意: 定义双回文串G是指一个可以被拆分成两个部分(S和T)的字符串G = S + T, 且S和T都是回文串的串, G自己本身可以不是回文串 给出一个长度为n ( 2 大致思路: 首先可以相当manacher算法当中有这样一个过程, 用两个辅助变量mx和p分别表示已有回文半径覆...
  • u013738743
  • u013738743
  • 2015-03-20 22:03
  • 1468

【BZOJ2565】最长双回文串 Manacher

Manacher拓展、
  • Vmurder
  • Vmurder
  • 2014-12-28 16:01
  • 930

JZOJ2682. 【WC2012选拔12.17】最长双回文串

Description顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。Input一行由小写英文字母组成的...
  • lijf2001
  • lijf2001
  • 2018-01-11 17:17
  • 26

bzoj2565: 最长双回文串

回文串。。。Manachar! 将Manachar的p数组转换为l[i](i为右端点往左最长的回文串),r[i](同理),然后O(n)搜一遍求最值即可。 p.s.Manachar的核心是枚举中心,利用之前的回文串的对称性,将当前中心对称到之前的中心。 #include #in...
  • Miao_zc
  • Miao_zc
  • 2016-03-11 20:55
  • 299

bzoj 2565: 最长双回文串 manachar

题意顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。 输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。 2≤|S|≤10^5分析直接用manacha...
  • qq_33229466
  • qq_33229466
  • 2017-10-20 21:18
  • 127

bzoj 2565: 最长双回文串 manacher

统计出以每一个点为回文中心最大能到哪,然后跑一个玄学的DP搞出每一个点左侧和右侧最远的回文串到哪然后扫一遍即可,具体可以看代码。(这份代码写的很垃圾)#include<cstdio> #include<cstdlib> #include<iostream> #in...
  • LZJ209
  • LZJ209
  • 2017-02-22 13:46
  • 166

bzoj 2565: 最长双回文串(manacher)

2565: 最长双回文串 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1605  Solved: 823 [Submit][Status][Discuss] Desc...
  • clover_hxy
  • clover_hxy
  • 2016-12-02 09:33
  • 195

BZOJ 2565: 最长双回文串 manacher

最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。 输入 一行由小写英文字...
  • BlackJack_
  • BlackJack_
  • 2017-06-09 19:24
  • 143
    -广告-
    一个极其温馨的提示
    个人资料
    • 访问:48712次
    • 积分:1745
    • 等级:
    • 排名:千里之外
    • 原创:127篇
    • 转载:1篇
    • 译文:0篇
    • 评论:23条
    最新评论