\(\texttt{Problem Link}\)

简要题意

在一个字符串 \(s\) 中,对于每个后缀,任意删掉一些相邻的相同的字符,使得字符串字典序最小。

注意:删掉之后拼起来再出现的相邻相同字符不能够删除。

思路

倍增好题

发现存在局部最优解(最优子结构),并且可以转移到其它结点,可以考虑使用 dp

那就设 \(f _ i\) 表示 \([i , n]\) 经过一些操作,达成的字典序最小的字符串(求后缀最优解,从后往前遍历)。

可以得到状态转移:

\[
f_i =

\begin{cases}

f_{i+1} + s_i, & s_i \neq s_{i+1},\\

\min \{f_{i+1} + s_i , f_{i+2}\} & s_i = s_{i+1}. \\
\end{cases}
\]

\(s_i\) 表示第 \(i\) 个字符,\(\min\) 表示字典序更小的那个。

边界条件:\(f_n = s_n\)。

但是这样做的复杂度是 \(\mathcal{O}(n^2)\)。

字典序比较优化

瓶颈在于比较字典序。

考虑对字典序比较进行优化。

回顾字典序比较的过程,

过程是对于两个字符串,从头到尾一个个字符进行比较,遇到第一个字符不同时,就返回答案。

那么就可以有一个想法通过一些操作,快速找到第一个不同的字符。

可以考虑使用倍增优化,把两个串比较时,通过倍增找到 hash 值第一个不同的地方,这样字符串比较就能优化到 \(\mathcal{O}(\log n)\)。

输出优化

接下来的问题就是输出,

因为输出长字符只要输出前 \(5\) 个和最后 \(2\) 个。

所以可以对于前面的字符直接输出,后面的字符也可以写个倍增往后跳到需要的。

最后总的复杂度就是 \(\mathcal{O}(n \log n)\)。

Code

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm> using i64 = long long ;
using ui64 = unsigned long long ; const int N = 1e5 + 5 ;
const int base = 131 ; char s[N];
int f[N] , g[N] , h[N];
ui64 Pow[100];
ui64 Hash[20][N];//自然溢出
int nxt[20][N];
int n; void updata(int u, int v){
v = h[v];
h[u] = u;
g[u] = g[v] + 1;//记录当前的长度
nxt[0][u] = v;
Hash[0][u] = s[u] - 'a'; for(int i = 1; i <= 19; i++)
nxt[i][u] = nxt[i-1][nxt[i-1][u]] , Hash[i][u] = Hash[i-1][u] * Pow[i - 1] + Hash[i-1][nxt[i-1][u]]; //处理hash倍增
// nxt是方便向后跳2^k的
} int min(int x, int y){
int tx = x , ty = y; x = h[x] , y = h[y]; for(int i = 19; i >= 0; i--)
if(nxt[i][x] && nxt[i][y] && Hash[i][x] == Hash[i][y])
x = nxt[i][x] , y = nxt[i][y];//找到第一个不同的字符 return Hash[0][x] < Hash[0][y]? tx: ty;//小细节不能写 <= 写 <= 会导致部分少删除
} int main(){ scanf("%s",s+1); n = strlen(s+1); Pow[0] = base;
for(int i = 1; i <= 90; i++)
Pow[i] = Pow[i - 1] * Pow[i - 1];//预处理 base 的 2^i 次方,方便将hash值拼起来 for(int i = n; i >= 1; i--) {
updata(i,i+1);//默认是接上字符 if(i < n && s[i] == s[i+1] && min(i,i + 2) == i + 2) {//删除更优
h[i] = h[h[i + 2]];
g[i] = g[h[i + 2]];
}
} for(int i = 1; i <= n; i++) {
printf("%d ",g[i]); int id = h[i];
if(g[i] <= 10) {
for(int j = id; j && j <= n; j = nxt[0][j])
putchar(s[j]);
} else {
for(int j = 1; j <= 5; j++ , id = nxt[0][id])//前5个字符直接暴力找
putchar(s[id]); printf("..."); id = h[i];
int len = g[i] - 2 ; for(int i = 19; i >= 0; i--)
if(nxt[i][id] && (1<<i) <= len) len -= 1<<i , id = nxt[i][id];//倍增找最后两个字符 for(int j = 1; j <= 2; j++ , id = nxt[0][id])
putchar(s[id]);
} puts("");
}
return 0;
}

牢骚

本来思路是完全正确的,但是我用了一个 Trie 树和递归找字符串,导致常数太大,真的气死人了。

Minlexes题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 记一次 .NET某列控连锁系统 崩溃分析

    一:背景 1. 讲故事 过年喝了不少酒,脑子不灵光了,停了将近一个月没写博客,今天就当新年开工写一篇吧. 去年年初有位朋友找到我,说他们的系统会偶发性崩溃,在网上也发了不少帖子求助,没找到自己满意的答 ...

  2. WriteFile 奇怪的现象

    项目中有个需求是要对文本内容检索并重写,我们使用的是 WriteFile 覆盖旧的文本内容 最小示例: #include <Windows.h> #include <iostream ...

  3. Go 项目的文件布局

    转自 kcq 的 https://github.com/golang-standards/project-layout https://github.com/golang-standards/proj ...

  4. Django重点

    Django 简述python三大主流web框架 """ django 大而全,类似于航空母舰 但是有时候过于笨重 flask 小而精,类似于游骑兵(单行代码就可以起一个 ...

  5. .NET Core 集成微信支付签名错误

    .NET Core 集成微信支付签名错误 The provided data is tagged with 'Universal' class value '16', but it should ha ...

  6. Golang标准库——io

    原文:Golang标准库--io 1.io io包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如os包里的原语),使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加 ...

  7. 05、secs协议常见问题分析以及如何建立通信

    1.建立通信 在主机和设备之间发送SECS-II消息之前,必须首先"建立"通信.这是通过S1F13(建立通信请求)消息来完成的.这应该是在初始启动后或在长时间不通信之后发送的第一个 ...

  8. 图数据库实操:用 Nebula Graph 破解成语版 Wordle 谜底

    本文首发于 Nebula Graph Community 公众号 春节期间如果有小伙伴玩过 Wordle 这个火爆社交媒体的猜词游戏,可能对成语版本的汉兜有所耳闻.在玩汉兜过程中,我发现用 Nebul ...

  9. 基于Ant Design设计语言的WinForm UI界面库

    前言 经常在技术群里看到有小伙伴提问:WinForm有什么好看.开源的UI库推荐的吗?,今天大姚给大家分享一款基于Ant Design(使用Ant Design 5.0)设计语言.开源(Apache ...

  10. js收藏网页功能,纠正网上乱转没求证的案例

    网站一般流行以下收藏代码 function AddFavorite(title, url){ try{ //ie收藏 window.external.addFavorite(url, title); ...