ZR#957
ZR#957
解法:
首先 $ T $ 必须得要是 $ S $ 的子序列,不然不存在好的下标序列,因此一定无解。
考虑判断一个串 $ T $ 是不是 $ S $ 子序列的贪心做法:每次从没有匹配的位置中,选择第一个和 $ T_i $ 一样的与 $ T_i $ 进行匹配。设这样得到的下标序列是 $ p_1, p_2, \cdots , p_m $ ,则显然这是一个好的下标序列。
从刚刚贪心的过程中,我们可以发现,$ p_1 $ 是所有可能的位置中最小的,$ p_2 $ 是在满足 $ p_1 $ 最小的情况下最小的,$ p_3 $ 是在满足 $ p_1, p_2 $ 都最小的情况下最小的 $ \cdots \cdots $ 则这样得到的序列是所有好的下标序列中,字典序最小的那个。
我们接下来考虑调整这个好的下标序列,使它变成优秀的。我们按照从后往前的顺序依次考虑 S 中所有满足相邻两个字母不同的位置,设为 $ i $ 和 $ i + 1 $ 。根据题意,我们要求 $ i $ 和 $ i + 1 $ 中至少有一个在这样的下标序列中,这样的下标序列才会是优秀的。
容易证明,对于所有这样的 $ i $ ,都满足 $ i $ 和 $ i + 1 $ 中的至少一个在序列中的好的下标序列一定是优秀的。
如果 $ i $ 或者 $ i + 1 $ 已经在序列 $ p $ 中了,那么已经符合条件了。否则,我们考虑调整:因为 $ p $ 已经是字典序最小的序列了,所以我们无法把某个 $ p_j $ 变得更小。因此,我们可以移动的位置一定是满足 $ p_j < i $ 的一段前缀。
因为 $ S_i \neq S_i+1 $,所以 $ T_j = S_i $ 或 $ T_j = S_i+1 $ 之一一定满足。于是,我们一定可以把 $ p_j $ 调整为 $ i $ 或 $ i + 1 $ 之一,从而使得 $ i $ 满足条件。如果有多个 $ j $ 满足这一条件,则我们应当选择最大的那个,容易证明这样一定不劣。如果不存在这样的 $ j $,根据 $ p $ 是字典序最小的好的序列,其他序列一定也不存在这样的 $ j $,因此一定无解。
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long
const int N = 3e5 + 100;
int m,n,p[N];
char a[N],b[N];
int main(){
scanf("%d%d",&n,&m);
scanf("%s%s",a + 1,b + 1);
for(int i = 1,j = 1 ; i <= m ; ++i) {
while(j <= n && a[j] != b[i]) ++j;
if(j > n) {
puts("-1");
return 0;
}
p[i] = j++;
}
a[0] = a[1];
for(int i = n,j = m ; i >= 1 ; --i) {
if(a[i] == a[i-1]) continue;
while(j >= 1 && p[j] > i) j--;
if(j <= 0) {
puts("-1");
return 0;
}
if(p[j] >= i-1) continue;
p[j] = a[i] == b[j] ? i : i-1;
}
for(int i = 1 ; i <= m ; i++)
printf("%d ",p[i]);
//system("pause");
return 0;
}
ZR#957的更多相关文章
- ORA-07445 [mdagun_iter+957] When Using SDO_AGGR_UNION 问题处理
问题描写叙述: ORA-07445: mdagun_iter() [Address not mapped to object] Oracle Database 10g Enterprise Edit ...
- [ERROR] InnoDB: Trying to access page number 7 in space 957, space name XXX which is outside the tablespace bounds
早上,测试说演示环境mysql老实断开重连,一update就挂,经查日志,有如下异常: 2017-04-05T23:13:01.729250+08:00 17065 [ERROR] InnoDB: T ...
- Leetcode 957.N天后的牢房
Leetcode 957.N天后的牢房 8间牢房排成一排,每间牢房不是有人住就是空着. 每天,无论牢房是被占用或空置,都会根据以下规则进行更改: 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该 ...
- ZR#1005
ZR#1005 解法: 题解给了一个建图跑最短路的做法,但好像没有必要,因为 $ m $ 没有用,所以直接上完全背包就行了. CODE: #include<iostream> #inclu ...
- ZR#1004
ZR#1004 解法: 对于 $ (x^2 + y)^2 \equiv (x^2 - y)^2 + 1 \pmod p $ 化简并整理得 $ 4x^2y \equiv 1 \pmod p $ 即 $ ...
- ZR#1009
ZR#1009 解法: 因为无敌的SR给了一个大暴力算法,所以通过打表发现了了一些神奇的性质,即第一行和第一列的对应位置数值相等. 我们可以通过手算得出 $ F(n) = \frac{n(n + 1) ...
- ZR#1008
ZR#1008 解法: 直接预处理出来执行完一个完整的串可以到达的位置,然后算出重复的次数直接乘在坐标上,最后处理一下余下的部分就行了. CODE: #include<iostream> ...
- ZR#1015
ZR#1015 解法: 我们需要求得, $ g_i $ 表示长度为的最长不下降子序列个数. 设 $ f_{i,j} $ 表示统计第前$ i $ 个数字,得到最长不下降子序列末端为 $ j $ . 显然 ...
- ZR#1012
## ZR#1012 blog咕咕咕了好久,开始补. 解法: 一个很显然的性质, $ x $ 只能转移到 $ x+1 $ 或者 $ 2x $ 处,所以我们可以以此性质建图,即 $ x $ 向 $ x ...
随机推荐
- SQL 多并发 多人取号,防止重复取号SQL 办法
BEGIN TRAN SELECT * from 表明 WITH(HOLDLOCK) UPDATE 表名 SET 值=1 WHERE 字段=@carrierNo; ...
- 无重复字符串的最长子串 python
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...
- robot framework 接口测试 http协议post请求json格式
robot framework 接口测试 http协议post请求json格式 讲解一个基础版本.注意区分url地址和uri地址. rf和jmeter在添加服务器地址也就是ip地址的时候,只能url地 ...
- Ipython 和 python 的区别
IPython是一个python交互shell,它比默认的python shell更易于使用.它支持自动变量完成.自动缩进.bash shell命令,并且内置了许多有用的函数和函数. IPython是 ...
- drf-过滤组件|分页组件|过滤器
目录 drf-过滤组件|分页组件|过滤器 群查接口各种筛选组件数据准备 drf过滤组件 搜索过滤组件 | SearchFilter 案例: 排序过滤组件 | OrderingFilter 案例: dr ...
- c++第五次博客作业
C++虚函数,纯虚函数,抽象类以及虚基类的区别 Part1.C++中的虚函数 什么是虚函数: 直观表达就是,如果一个函数的声明中有 virtual 关键字,那么这个函数就是虚函数. ...
- jFinal手册
JFinal官方文档 https://www.jfinal.com/ w3cschool之JFinal手册 https://www.w3cschool.cn/jfinal/
- POI进行导出时候发现有不可读取的内容
通过后台查询数据,然后使用poi进行导出时候,excel进行打开会出现下面的异常: 但是在WPS中就没有问题, 如果点击否,则不会显示任何内容,点击是,就会弹出来 查看修改记录为: 刚开始也进行了很多 ...
- 我的 archlinux 内核参数配置
title Arch Linux linux /vmlinuz-linux initrd /amd-ucode.img initrd /initramfs-linux.img options root ...
- 聊聊Hash索引
hash index是基于哈希表实现的,只有精确匹配索引所有列的查询才会生效.对于每一行数据,存储引擎都会对所有的索引列计算一个hash code,并将的有的hash code存储在索引中,同时在哈希 ...