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的更多相关文章

  1. ORA-07445 [mdagun_iter+957] When Using SDO_AGGR_UNION 问题处理

    问题描写叙述: ORA-07445: mdagun_iter()  [Address not mapped to object] Oracle Database 10g Enterprise Edit ...

  2. [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 ...

  3. Leetcode 957.N天后的牢房

    Leetcode 957.N天后的牢房 8间牢房排成一排,每间牢房不是有人住就是空着. 每天,无论牢房是被占用或空置,都会根据以下规则进行更改: 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该 ...

  4. ZR#1005

    ZR#1005 解法: 题解给了一个建图跑最短路的做法,但好像没有必要,因为 $ m $ 没有用,所以直接上完全背包就行了. CODE: #include<iostream> #inclu ...

  5. ZR#1004

    ZR#1004 解法: 对于 $ (x^2 + y)^2 \equiv (x^2 - y)^2 + 1 \pmod p $ 化简并整理得 $ 4x^2y \equiv 1 \pmod p $ 即 $ ...

  6. ZR#1009

    ZR#1009 解法: 因为无敌的SR给了一个大暴力算法,所以通过打表发现了了一些神奇的性质,即第一行和第一列的对应位置数值相等. 我们可以通过手算得出 $ F(n) = \frac{n(n + 1) ...

  7. ZR#1008

    ZR#1008 解法: 直接预处理出来执行完一个完整的串可以到达的位置,然后算出重复的次数直接乘在坐标上,最后处理一下余下的部分就行了. CODE: #include<iostream> ...

  8. ZR#1015

    ZR#1015 解法: 我们需要求得, $ g_i $ 表示长度为的最长不下降子序列个数. 设 $ f_{i,j} $ 表示统计第前$ i $ 个数字,得到最长不下降子序列末端为 $ j $ . 显然 ...

  9. ZR#1012

    ## ZR#1012 blog咕咕咕了好久,开始补. 解法: 一个很显然的性质, $ x $ 只能转移到 $ x+1 $ 或者 $ 2x $ 处,所以我们可以以此性质建图,即 $ x $ 向 $ x ...

随机推荐

  1. Go 互斥锁(sync.Mutex)和 读写锁(sync.RWMutex)

    什么时候需要用到锁? 当程序中就一个线程的时候,是不需要加锁的,但是通常实际的代码不会只是单线程,所以这个时候就需要用到锁了,那么关于锁的使用场景主要涉及到哪些呢? 多个线程在读相同的数据时 多个线程 ...

  2. 用Python爬取小说《一念永恒》

    我们首先选定从笔趣看网站爬取这本小说. 然后开始分析网页构造,这些与以前的分析过程大同小异,就不再多叙述了,只需要找到几个关键的标签和user-agent基本上就可以了. 那么下面,我们直接来看代码. ...

  3. vue滚动分页加载以及监听事件处理

    <template> <div class="bodyContainer"> <div class="allContent" id ...

  4. Windows10 图标变白修复

    Windows10 图标变白修复 本文作者:天析 作者邮箱:2200475850@qq.com 发布时间: Tue, 16 Jul 2019 10:54:00 +0800 这种问题多半是ico缓存造成 ...

  5. Android NDK 学习之在C中调用Java的变量和静态变量

    本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...

  6. node.js 接口调用示例

    测试用例git地址(node.js部分):https://github.com/wuyongxian20/node-api.git 项目架构如下: controllers: 文件夹下为接口文件 log ...

  7. 如何使用python自定义命令

    dir.tree.cd等等,都是我们常见的命令.这些命令是开发者开发出来的,如果我们自己想按照自己的想法开发一个命令,应该怎么做呢? 以python语言来实现,问题就是:如何使用python自定义命令 ...

  8. 协议形式化安全分析 Scyther 并非所有协议可以照抄就搬

    1.Scyther 形式化分析工具可以对协议进行形式化描述,验证协议的机密性和可认证性是否存在安全威胁.在攻击时支持会话轮数无限次执行,同时支持在强安全模型和Delov-Yao模型.在对要形式化分析的 ...

  9. Python_赋值运算符

    1.赋值运算符

  10. 每日一题-——LeetCode(121)买卖股票的最佳时机

    题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格.如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润.注意你不能在买入股票前卖出股票 ...