\(\text{Problem}\)

\(\text{Solution}\)

最优解一定是一个回文子串的最优构造加上剩下的逐个填入

考虑用回文树建出所有的回文串,然后 \(dp\) 求回文子串最优的构造方案

维护一个 \(\text{half}\) 意义同 \(\text{fail}\),但要保证长度不超过 \(len\) 的一半且最大

暴力跳 \(\text{fail}\) 发现不行

加上一个小 \(\text{trick}\):倒着做,用 \(x\) 的 \(\text{half}\) 更新 \(\text{fail[x]}\) 的 \(\text{half}\)

正确性显然

\(\text{Code}\)

#include <cstdio>
#include <cstring>
#include <iostream>
#define re register
using namespace std; const int N = 1e5 + 5;
int T, Len;
char str[N]; struct PAM{
int size, last, tot, tr[N][26], fail[N], half[N], len[N], f[N], fa[N];
char s[N];
inline int Node(int l)
{
++size, memset(tr[size], 0, sizeof tr[size]);
len[size] = l, fail[size] = half[size] = 0;
return size;
}
inline void clear()
{
size = -1, s[last = tot = 0] = '$';
Node(0), Node(-1), fail[0] = 1;
memset(f, 0, sizeof f), f[0] = 1;
}
inline int getfail(int x)
{
while (s[tot - len[x] - 1] != s[tot]) x = fail[x];
return x;
}
inline void insert(char c)
{
s[++tot] = c;
int cur = getfail(last), ch = c - 'a';
if (!tr[cur][ch])
{
int u = Node(len[cur] + 2);
fail[u] = tr[getfail(fail[cur])][ch], fa[u] = cur, tr[cur][ch] = u;
}
last = tr[cur][ch];
}
inline void gethalf()
{
for(re int i = 2; i <= size; i++) half[i] = fail[i];
for(re int i = size; i >= 2; i--)
{
while ((len[half[i]] << 1) > len[i]) half[i] = fail[half[i]];
if (len[half[i]] < len[half[fail[i]]]) half[fail[i]] = half[i];
}
}
inline int dp()
{
int ans = Len;
for(re int i = 2; i <= size; i++)
{
if (len[i] & 1) f[i] = min(f[fa[i]] + 2, f[fail[i]] + len[i] - len[fail[i]]);
else f[i] = min(f[fa[i]] + 1, f[half[i]] + (len[i] >> 1) - len[half[i]] + 1);
ans = min(ans, f[i] + Len - len[i]);
}
return ans;
}
}P; int main()
{
scanf("%d", &T);
for(; T; --T)
{
P.clear();
scanf("%s", str + 1);
Len = strlen(str + 1);
for(re int i = 1; i <= Len; i++) P.insert(str[i]);
P.gethalf();
printf("%d\n", P.dp());
}
}

JZOJ 4752.字符串合成的更多相关文章

  1. [JZOJ 5129] 字符串

    题意:统计本质不同的串的个数. 思路: 显然后缀自动机,对于每个串建一个\(SAM\)统计即可. #include <bits/stdc++.h> using namespace std; ...

  2. Add Binary字符数字相加,字符串合成

    Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...

  3. Python中常见字符串去除空格的方法总结

    Python中常见字符串去除空格的方法总结 1:strip()方法,去除字符串开头或者结尾的空格>>> a = " a b c ">>> a.s ...

  4. Python处理字符串和列表元组的小技巧

    变量值互换 a = 1 b = 100 # 变量值互换 a, b = b, a print('a:', a) print('b:', b) 输出结果: a: 100 b: 1 多个变量赋值 a, b, ...

  5. Torch7学习笔记(一)CmdLine

    该类主要为了提供一种方便解析参数的框架,对于每个实验尤其是神经网络中要调参数上.同时还可以把输出重定向到log文件中. 一般用法: cmd = torch.CmdLine() cmd:text() c ...

  6. Python 学习---------Day2

    第四章 介绍Python对象类型为什么使用内置类型 内置对象使程序更容易编写 内置对象是拓展的组件 内置对象往往比定制的数据结构更有效率 内置对象是语言标准的一部分Python的核心数据类型 数字 字 ...

  7. JavaScript——exec和match

    题目17:Read the following javascript code: var someText="web2.0 .net2.0";var pattern=/(\w+)( ...

  8. C#文件系统管理

    目录 前言 Directory类和DirectoryInfo类 File类和FileInfo类 Path类 前言 管理文件系统主要是对计算机中文件和目录的管理,例如,读取文件信息.删除文件和读取目录信 ...

  9. JS中exec函数与match函数的区别与联系

    总结: 正则规则的声明,两种方法: exec是RegExp类的匹配方法 match是字符串类的匹配方法 var reg = /aaa/g; var reg = new RegExp("aaa ...

  10. 科大讯飞和Tizen-TTS语音合成引擎

    最近在做一个文本转语音TTS(Text to Speech)的第三方软件封装,使用的是国内语音技术龙头安徽科大讯飞公司提供的离线引擎AiSound5.0,主要用于汽车导航用途.科大讯飞还提供 了AiT ...

随机推荐

  1. TypeError: Object(…) is not a function

    vue中遇到的这个错误 1. 先检查变量名或者函数名是否有重复定义 报这错之后看了好久,也没有发现starkflow上说的,重复定义了变量或者函数 2. vue的话 检查下函数写的位置,直接写到cre ...

  2. Spring IoC的一些知识点

    在日常开发中,接触得比较多的算是Spring生态了,Spring Ioc是Spring Framework重要的组成部分,下面整理了一些Spring Ioc的知识点. 1. 什么是IoC IoC(In ...

  3. c++随笔测试(Corner of cpp)

    在c++17下,程序的输出是什么?(有可能编译出错,有可能输出未知,有可能是未定义行为) 点击查看代码 #include<iostream> void foo(unsigned int) ...

  4. git使用与代码托管

    平时自己写的简单程序文件太多,可以放到代码托管的网站.比如国内的gitee.com, 好吧,只是把这个网站当网络云盘用了.在gitee网站上加上程序运行环境,使用文档,写好README.md使用介绍. ...

  5. [OpenCV实战]18 Opencv中的单应性矩阵Homography

    目录 1 介绍 1.1 什么是Homography 1.2 使用Homography进行图像对齐 1.3 Homography的应用-全景拼接 2 Homography的计算 3 总结 4 参考 &l ...

  6. [python] 基于matplotlib_venn实现维恩图的绘制

    文章目录 VENN DIAGRAM(维恩图) 1. 具有2个分组的基本的维恩图 Venn diagram with 2 groups 2. 具有3个组的基本维恩图 Venn diagram with ...

  7. 如何指定多个项目的 InternalsVisibleTo

    InternalsVisibleTo 属性允许你指定一个或多个程序集,这些程序集可以访问当前程序集中的内部类型.经常在进行单元测试时使用,例如,你可以在一个项目中定义一个内部类型,然后在另一个项目中进 ...

  8. 1_使用swiper数组对象循环图片遇到的问题

    今天在练习微信小程序的swiper组件时,想用列表循环出图片,发现图片一直没出来,控制台也没有报错,后来仔细一看,原来是语法格式写错了. 以下是我列表循环踩过的坑: 一:微信小程序的列表循环和vue的 ...

  9. Java学习笔记:2022年1月10日

    Java学习笔记:2022年1月10日 ​ 摘要:这篇笔记主要记录了学习<Java核心技术 卷一>的第四章时的一些心得,主要阐述了对象与类这一部分的内容.需要注意的是,这一章的内容需要精心 ...

  10. SPOJLCMSUM - LCM Sum

    简要题意 \(T\) 组数据,每组数据给出一个 \(n\),计算: \[\sum_{i=1}^{n}{\operatorname{lcm}(i,n)} \] \(1 \leq T \leq 3\tim ...