【border相关】【P3426】 [POI2005]SZA-Template

Description

给定一个字符串 \(S\),要求一个最短的字符串 \(T\),使得 \(S\) 可以由 \(T\) 不断在后面接上自身得到。在拼接的时候, \(T\) 的某个后缀如果与某个前缀相同,则相同的部分可以算作一个,不再重复出现。

Limitations

\(1 \leq |S| \leq 5 \times 10^5\)

Solution

介绍一个叫 \(border\) 树的东西,在 OI 中被称作 \(next\) 树。

记 \(S\) 的前缀 \(i\) 的最长 \(border\) 为 \(border_i\),考虑在 \(i\) 和 \(border_i\) 之间连一条边,最终会形成一棵以 \(0\) 为根的树。

证明上,考虑这棵树有 \(n + 1\) 个节点,而显然 \(border_i < i\),因此每个节点连向 \(border\) 的边都是互不重复的,共有 \(n\) 条边,由此可以证明这是一颗树。

这棵树有两个优美的性质:

节点 \(u\) 的祖先集合是 \(u\) 的所有 \(border\) 集合

节点 \(u\) 的后代集合是 \(u\) 能作为 \(border\) 的 \(S\) 的前缀子串集合

对于性质 \(1\),根据定义,\(u\) 的父节点是 \(u\) 的最长 \(border\),迭代证明即可。

性质 \(2\) 可以由性质 \(1\) 反推得到。

现在考虑本题。

一个显而易见的结论是 \(T\) 一定是 \(S\) 的 \(border\)。

因此我们考虑枚举 \(S\) 的所有 \(border\),我们发现对于长度为 \(i\) 的 \(border\),如果将他在 \(border\) 树上的后代拿下来排序以后相邻两数差值的最大值大于 \(i\),则这个 \(border\) 不能作为答案,因为对于插值最大的两个数,在拼接到左边的位置以后再加一个长度为 \(i\) 的 \(T\) 不能拼接到右侧的数,反之可以证明这个 \(border\) 是合法的。

我们考虑维护 \(border\) 的所有后代,从长到短枚举 \(border\) 时,相当于从 \(border\) 树的某个叶节点一直枚举到根,我们发现 \(border\) 变短时只会加入一些节点而不会删除,因此用一个 set 去维护这些后代,用 multiset 维护插值最大值即可。

时间复杂度 \(O(|S| \log |S|)\)

Code

写代码的时候发现一个有关 multiset 的有趣的事:erase某个值的时候,会将全部的该值删掉,如果想要只删掉一个,需要 s.erase(s.find(x))

#include <cstdio>
#include <set>
#include <vector>
#include <algorithm>const int maxn = 500005;int n, ans;
char MU[maxn];
int border[maxn];
std::set<int>s;
std::multiset<int>ms;
std::vector<int>son[maxn];void KMP();
int ReadStr(char *p);
void dfs(const int u);
void update(const int x);void KMP();int main() {freopen("1.in", "r", stdin);n = ReadStr(MU + 1);KMP();update(n);for (int i = border[n], j = n; i; j = i, i = border[i]) {update(i);for (auto u : son[i]) if (u != j) {dfs(u);}if (*(--ms.end()) <= i) {ans = i;}}qw(ans, '\n', true);return 0;
}int ReadStr(char *p) {auto beg = p;do *p = IPT::GetChar(); while ((*p > 'z') || (*p < 'a'));do *(++p) = IPT::GetChar(); while ((*p >= 'a') && (*p <= 'z'));*p = 0;return p - beg;
}void KMP() {for (int i = 2, j = 0; i <= n; ++i) {while (j && (MU[i] != MU[j + 1])) j = border[j];if (MU[i] == MU[j + 1]) ++j;son[border[i] = j].push_back(i);}
}void dfs(const int u) {update(u);for (auto v : son[u]) {dfs(v);}
}void update(const int x) {auto u = s.insert(x).first, ftmp = u, btmp = u;--ftmp; ++btmp;if ((u != s.begin()) && (btmp != s.end())) {ms.erase(ms.find(*btmp - *ftmp));}if (u != s.begin()) {ms.insert(x - *ftmp);}if (btmp != s.end()) {ms.insert(*btmp - x);}
}

转载于:https://www.cnblogs.com/yifusuyi/p/11470747.html

【border相关】【P3426】 [POI2005]SZA-Template相关推荐

  1. 洛谷P3426 [POI2005]SZA-Template 题解

    洛谷P3426 [POI2005]SZA-Template 题解 题目链接:P3426 [POI2005]SZA-Template 题意:你打算在纸上印一串字母. 为了完成这项工作,你决定刻一个印章. ...

  2. P3426 [POI2005]SZA-Template

    洛谷博客链接 P3426 [POI2005]SZA-Template - 传送门 题意 给你一字符串,需要你制作一个印章,能用它盖出该字符串(当然不能多盖). 求最小印章长度. 盖印章: 同一位置,一 ...

  3. 边框border相关属性以及其他注意点

    一.边框 border 单独设置 border-top:边框的宽度 边框的线型 颜色:(顺序可以随便调) border-bottom border-left border-right 线型 实线 so ...

  4. P3426 [POI2005]SZA-Template(kmp+dp)

    https://www.luogu.com.cn/problem/P3426 这题出得挺好的,代码量简洁但是却有一定思维量. 先说一下暴力做法,不难看出如果要完成这一工作,必然和前后缀有关,如果当前i ...

  5. 洛谷 P3426 [POI2005]SZA-Template

    括弧,这是一个错误的做法,并不能AC 题目描述 Byteasar wants to put a rather long pattern on his house. In order to do thi ...

  6. P3426 [POI2005]SZA-Template(kmp、dp)

    解析 做出来了就是胜利! 个人感觉虽然我这个nxt树的码量会大一点,但是思路其实比较自然.(看题解区也有) 也是一个相当可取的做法. 现在来讲讲巧妙的dp做法. 考虑直接嗯设:fif_ifi​ 表示覆 ...

  7. elementUI中radio的相关使用

    elementUI中radio的相关使用 radio的使用 change:绑定值变化时触发的事件 <template><div style="padding:20px;&q ...

  8. Python 网络服务相关 杂记

    个人所有文章整理在此篇,将陆续更新收录:知无涯,行者之路莫言终(我的编程之路) 本文杂记了下面一些点 [1].Python的原生版Socket [2].python自带的模块:`wsgiref`的简单 ...

  9. java border边框_简单实用的css边框属性border

    本文主要讲述利用border属性做出不同的几何形状从而适用于比较好看的视觉样式. 预备知识 border相关属性 border-width 边框的宽度 border-style 边框的样式 borde ...

最新文章

  1. mysql启用keepalive_keepalive+mysql 主主配置
  2. Javascript Tip(1) 操作剪贴板
  3. HikariPool使用MySQL/MariaDB数据库报错解决:java.sql.SQLException: Access denied for user 'root'@'localhost' (u
  4. abb智能控制系统_ABB助力国网冀北电力打造虚拟电厂
  5. 深入理解BodyTagSupport,包括SKIP_PAGE, EVAL_PAGE等
  6. Cisco1721的简单配置
  7. 移动硬盘新建选项消失、不能新建文件夹和文件的解决方案
  8. 若依微服务部署遇到问题
  9. Centos7 搭建 hadoop3.1.1 集群教程
  10. win7系统升级到ie11浏览器(常见错误,升级经验)
  11. msdtc.exe是微软分布式传输协调程序。该进程调用系统Microsoft Personal Web Server和Microsoft SQL Server。该服务用于管理多个服务
  12. WinRM(Windows远程管理)介绍,Python远程操作Windows
  13. 百度网盘下载太慢,试试阿里云网盘?
  14. 【VUE】实现分页组件
  15. 数据结构与算法:1.链表结构
  16. [Python]远程SSH库Paramiko简介
  17. 光标变成黑色怎么解决
  18. 区分原生IP和广播IP
  19. 基于jeesite+android开发 电子商务系统免费教程
  20. 谁会嫌钱多啊,最适合学生党的Python兼职攻略以及接私活经验

热门文章

  1. 如何安装鸿蒙应用,华为鸿蒙OS系统手机怎么安装第三方的应用程序?
  2. csgo如何保存自己的cfg_CSGO进阶教程:cfg文件调试指南
  3. 杨辉三角与二项式定理
  4. 基于STM32MP157的鸿蒙学习(一)— 资料下载及入门
  5. MDWechat(微信美化)免费
  6. mysql ibd文件一直增加_为什么 MySQL 回滚事务也会导致 ibd 文件增大?
  7. Pytorch:定义的网络结构层能否重复使用
  8. 墨者_密码学加解密实训(摩斯密码第1题)
  9. 四代增强 (BTE实例详解)
  10. 计算机放音乐声音小在吗调,笔记本外放声音太小怎么办?-电脑教程