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 ...
随机推荐
- 解读生命密码的基本手段 ——DNA测序技术的前世今生
解读生命密码的基本手段 ——DNA测序技术的前世今生 任鲁风 于军 (中国科学院基因组科学及信息重点实验室,北京基因组研究所) DNA(脱氧核糖核酸)和RNA(核糖核酸)是生命体的两种最基本组成物质 ...
- elementUI表单验证
elementUI表单验证非常方便,我们直奔主题: <template> <el-form ref="orderForm" :model="orderF ...
- English-培训5-How much is it
- stm32内联汇编
首先,先看一下mdk下的混合编程的基本方法: 使用如上方法就可以进行混合编程了. 但是要特殊注意一点,个人感觉这个是直接调用一个代码段,并非一个函数,因为他不会保护调用这个代码段之前的现场.比如: 在 ...
- Vue路由的使用和route-link router-view样式和动画的设置
什么是路由 后端路由:**对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源: 前端路由:**对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面 ...
- scrapy框架介绍
一,介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性 ...
- Flutter——AlertDialog组件、SimpleDialog组件、showModalBottomSheet组件(弹窗组件)
AlertDialog组件 import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: " ...
- C++——调用优化
原始代码 #include<iostream> using namespace std; class Test { public: //以参数列表形式对数据成员进行初始化 Test() : ...
- python函数名的应用、闭包和迭代器
一.函数名的应用(第一类对象) 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数变量. 1.函数名的内存地址 def func(): print("哈哈") prin ...
- Multiple inheritance in Go
原文:http://golangtutorials.blogspot.com/2011/06/multiple-inheritance-in-go.html --------------------- ...