「Luogu P4987」回文项链 解题报告
题面
求环中的长度为k(k为奇数)且回文中心不同的回文串个数
思路:
刚学manacher算法,就送上一道模板题,此题注重对manacher算法的理解
Manacher,但是不用插入其他符号,因为k是奇数,中心一定在字符上
不知道Manacher?
洛谷日报上有讲,但是比较难懂,建议上B站更深入了解下\(\to\)
可以先把代码抄下来,然后一边看讲解一边理解代码含义,这样更能理解
反正我第一遍已经看蒙了
补充和纠正:
关于前几篇题解,一些小细节纠正一下
文末的代码更加简洁易懂
1、这是一个环,要做Manacher就应该拆环为链,第一篇题解说:应该重复复制三次(扩展为原来的三倍),但是实际上两次(扩展为原来的两倍)就够了
2、p数组(p[i])表示的是以i为中心的最长回文串的半径(包括i这个字符),原本的Manacher算法因为加入的额外的#号,而是p[i]表示的是就是原本最长回文串的长度+1,因此求Ans的时候应该用p[i]-1,但是现在我们不加#号了,p[i]表示的就是以i为中心的最长回文串的半径,此时长度就应该表示为p[i]*2-1,意思是半径*2-回文中心重复计算的字符
Code:
#include<bits/stdc++.h>
#define N 1000010//N<<1表示长度扩展为原来的两倍
using namespace std;
int n,k,p[N<<1],ans,res;
char s[N<<1];
void manacher()//标准的Manacher算法,就是没有加'#'号,而且起点为1
{
s[0]='?';
s[2*n+1]='!';
int id=0,mx=0;//id表示目前最长回文串的中心,mx则是右边界
for(int i=1;i<=2*n;i++)
{
if(i<mx)
p[i]=min(p[2*id-i],mx-i);//如果中心在mx范围内,用mx去更新p[i]
else
p[i]=1;
while(s[i-p[i]]==s[i+p[i]])//然后暴力
p[i]++;
if(mx<i+p[i])//更新mx和id
{
id=i;
mx=i+p[i];
}
}
return;
}
int main()
{
int i;
scanf("%d%d",&n,&k);
scanf("%s",s+1);
for(i=1;i<=n;i++)//复制
s[i+n]=s[i];
manacher();//跑一遍Manacher
res=(k+1)>>1;//表示起始的中心i的位置,这个位置是第一个有可能长度为k的回文串的中心(串s[1-k]的中心)
for(i=res;i<=res+n-1;i++)//对于每一个点遍历一次,所以是res+n-1
if(p[i]*2-1>=k)//真正的长度只要大于等于k就是可以的(大于k的可以把他砍成k啊~)
ans++;
printf("%d",ans);
return 0;
}
推荐题目:
一道有趣的黄题 P1210 回文检测
「Luogu P4987」回文项链 解题报告的更多相关文章
- 「Luogu P1210」回文检测 解题报告
题面 这是一道诡异的黄题 居然让你求一串吧啦吧啦的东西中 字母(大小写)最长的回文串的长度,还要输出完整的串 吐血 思路: 保持淡定,我们啥都不会,就会Manacher,那就用Manacher大法! ...
- 「Luogu P1435」回文字串 解题报告
题面 主要大衣大意: 给定一个字符串,求至少加入多少个字符才能使字符串变成回文字符串 下面就是我一本正经的胡说八道题解 思路: 很显然,这应该是一道典型的最长公共子序列的题目 因此,主要思想就是DP ...
- 「Luogu P3866」[TJOI2009]战争游戏 解题报告
题面 好难表述啊~ 在n*m的矩阵上,有一些大兵(为0),一些空地(一个正整数),障碍物(-1),现在摧毁一些空地,使所有大兵不能走出矩阵去(代价为表示空地的整数),求最小代价 思路: 网络流最小割 ...
- 「Luogu P2015」二叉苹果树 解题报告
题面 一个二叉树,边数为n\((2<n\le 100)\),每条边有一个权值,求剪枝后剩下p\((1<p<n)\)条边,使p条边的权值和最大 还看不懂?-- 2 5 input:5 ...
- 【九度OJ】题目1192:回文字符串 解题报告
[九度OJ]题目1192:回文字符串 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1192 题目描述: 给出一个长度不超过1000的 ...
- Solution -「LOJ #141」回文子串 ||「模板」双向 PAM
\(\mathcal{Description}\) Link. 给定字符串 \(s\),处理 \(q\) 次操作: 在 \(s\) 前添加字符串: 在 \(s\) 后添加字符串: 求 \(s\ ...
- leetcode 214. 最短回文串 解题报告
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa" 输出: "aaa ...
- 洛谷 P4555 [国家集训队]最长双回文串 解题报告
P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...
- 「CTS2019 | CTSC2019」氪金手游 解题报告
「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...
随机推荐
- @noi - 172@ 追捕大象
目录 @description@ @solution@ @accepted code@ @details@ @description@ 在一块平原上有一头大象. 平原被分成 n×m 个格子.初始时大象 ...
- Python--day66--Django模板语言关于静态文件路径的灵活写法
静态文件路径的灵活写法: 正规的讲解: 静态文件相关 {% static %} {% load static %} <img src="{% static "images/h ...
- 条件随机场(CRF) - 1 - 简介
声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,由于本人在学习初始时有很多数学知识都已忘记,所以为了 ...
- codedecision P1112 区间连续段 题解 线段树
题目描述:https://www.cnblogs.com/problems/p/P1112.html 题目链接:http://codedecision.com/problem/1112 线段树区间操作 ...
- joinColumns和inverseJoinColumns的用法
最近在工作中使用springside,里面用到了hibernate的多对多 一开始我在配置department(部门表)和menu(栏目表)的时候,这样写的. Department实体类中的getMe ...
- H3C HDLC协议使用限制
- H3C 路由环路
- linux 手动睡眠
在 Linux 内核的之前的版本, 正式的睡眠要求程序员手动处理所有上面的步骤. 它是一 个繁琐的过程, 包含相当多的易出错的样板式的代码. 程序员如果愿意还是可能用那种方 式手动睡眠; <li ...
- 一个基于 Slab 缓存的 scull: scullc
是时候给个例子了. scullc 是一个简化的 scull 模块的版本, 它只实现空设备 -- 永久 的内存区. 不象 scull, 它使用 kmalloc, scullc 使用内存缓存. 量子的大小 ...
- LeekCode解题记录
昨天晚上有个LeekCode的比赛,两个半小时解五题,轻松解决前两题后,卡在第三题,还剩半小时时放弃,开始解第五题,解完但未验证通过,第四题只看了下题目. 排名第一的大佬只用了36分钟全部写完. 差距 ...