Description

​ “全”在十分愉快打工,第0天,给了他一个仅有小写字母构成的长度为N的字符串S0,在之后的第i天里,“全”的工作是将Si−1复制一份到一个新的字符串Si中,在接下来的描述中,我们用Si[j]表示串Si中的第j个字符

然而“全”十分不熟练,在复制的时候他容易出错。比如说在复制Si−1[j]到Si[j]的时候有时他会把Si[j]上的字符写成Si[j−1]Si[j−1],而不是本应被写上去的Si−1[j],更具体一点就是新串中的字符Si[j]可能等于Si[j−1]或者Si−1[j]

这让“全”很困扰,现在他给你S0和另一个长度同样为N的字符串T,希望你求出一个最小的i,能满足Si=T,如果不存在这样的i,输出−1

Input

​ 第一行一个正整数N

第二行一个字符串S0

第三行一个字符串T

Output

​ 输出最小的满足条件的i,无解输出−1

Sample Input

#Sample1
5
abcde
aaacc #Sample2
5
abcde
abcde #Sample3
4
acaa
aaca #Sample4
5
abcde
bbbbb

Sample Output

#Sample1
2 #Sample2
0 #Sample3
2 #Sample4
-1

HINT

数据范围:

​ 对于100%的数据,1<=N<=10^6,全部都是小写字母

样例解释:

​ Sample1:S0=abcde,S1=aaccc,S2=aaacc

Sol

神题。

我们首先可以预处理出来T中每一个字符是从S中的哪一个位置推过来的,记为\(c[i]\)。

我们从右向左遍历,如果遇到了连续字母段的尾部则停下,并且设这个位置为i。

接着我们可以把S中一个字符的移动轨迹视为一条折线,显然对于T中一段相同的字母段,是用同一条折线转移过来的。而我们的答案就是折线的横边个数,因为折线的纵线没有意义,而横线就是每次染到的位置。

我们考虑使用双端队列维护折线的每个横线的右端点,显然每时每刻队列中只会描述一个折线,而对于不同的折线,显然我们发现前面的折线先多拐一个弯(避开上一条折线),然后贴着后面的走,直到碰到某个字母段的最后一个字母停止,后面的不继承了。

如果出现了\(s[i]==t[i]\)的情况,那么我们把队列清空,把接下来要处理的折线放进队列,因为被\(s[i]==t[i]\) 隔开的东西是互不影响的(\(c[i]\)和i连线是不可能相交的)。

上幅图形象解释一下:

我们的目标是让一个折线到达某个字母连续段的最后一位,如果继承的折线已经超过了这个位置\(i\),那么后面的折线不会再有意义,直接舍去即可,舍去完之后把当前折线的终点(就是i)再pushback进去就是当前完整的折线。而且我们发现每个折线继承部分都是上一个折线的某一部分,但是由于上一个折线的作用,折线又不能相交,所以我们还是需要把新的折线多拐一次,即上面红线部分,在遇到右边折线的时候要拐一个弯,这个pushfront即可。(中间部分完全认为是原来折线+偏移量)

同时我们维护一个全局变量lz,表示遇到了多少个折线,作用就是我们可以快速计算某个折线由于前面折线而往左偏移了多少。因为我们发现每次继承的拐点正好左移一位。

每条折线的长度取max就是答案。

Code

代码其实还不到1K。

#include <bits/stdc++.h>
using namespace std;
char a[1000005],b[1000005];int n,ok,c[1000005],lz,ans,cnt;vector<int>v[30];deque<int>q;
int main()
{
scanf("%d%s%s",&n,a+1,b+1);c[n+1]=n+1;
for(int i=1;i<=n;i++) ok+=a[i]==b[i];
if(ok==n) return puts("0"),0;
if(n==1) return puts("-1"),0;
for(int i=1;i<=n;i++) v[a[i]-'a'].push_back(i);
for(int i=n;i;i--)
{
if(b[i]==b[i+1]&&i>=c[i+1]){c[i]=c[i+1];continue;}
else
{
while(!v[b[i]-'a'].empty()&&v[b[i]-'a'].back()>=c[i+1])
{
v[b[i]-'a'].pop_back();
if(v[b[i]-'a'].empty()) return puts("-1"),0;
}
c[i]=v[b[i]-'a'].back();
if(i>=c[i+1])
{
lz--;q.push_front(c[i+1]-lz-1);
while(q.back()+lz>=i) q.pop_back();
q.push_back(i-lz);
}
else{while(!q.empty()) q.pop_back();if(c[i]<i) q.push_back(i-lz);}
ans=max(ans,(int)q.size());
}
}
cout<<ans<<endl;
}

[agc007f] Shik and Copying String 模拟神题的更多相关文章

  1. hdoj5821【贪心-神题】

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊,比赛的时候直接读错题了,实力带坑队友.... 题意: 有两个序列都代表筐,每个筐里只有一个球,然后序列的值代表筐里的球的颜色,问你在m次操作后,a序列的球能否变成b ...

  2. POJ 2014:Flow Layout 模拟水题

    Flow Layout Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3091   Accepted: 2148 Descr ...

  3. HDOJ 2317. Nasty Hacks 模拟水题

    Nasty Hacks Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  4. POJ 2484 A Funny Game(神题!)

    一开始看这道博弈题的时候我就用很常规的思路去分析了,首先先手取1或者2个coin后都会使剩下的coin变成线性排列的长条,然后无论双方如何操作都是把该线条分解为若干个子线条而已,即分解为若干个子游戏而 ...

  5. BUAA 724 晴天小猪的神题(RMQ线段树)

    BUAA 724 晴天小猪的神题 题意:中文题,略 题目链接:http://acm.buaa.edu.cn/problem/724/ 思路:对于询问x,y是否在同一区间,可以转换成有没有存在一个区间它 ...

  6. Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status ...

  7. SAC E#1 - 一道神题 Sequence1

    题目背景 小强和阿米巴是好朋友. 题目描述 小强很喜欢数列.有一天,他心血来潮,写下了一个数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种:波动数列. 一个长度为n的波动数列满足对于任何i(1 < ...

  8. 【CF913F】Strongly Connected Tournament 概率神题

    [CF913F]Strongly Connected Tournament 题意:有n个人进行如下锦标赛: 1.所有人都和所有其他的人进行一场比赛,其中标号为i的人打赢标号为j的人(i<j)的概 ...

  9. AtCoder 神题汇总

    记录平时打 AtCoder 比赛时遇到的一些神题. Tenka1 Programmer Contest 2019 D Three Colors 题目大意 有 $n$ 个正整数 $a_1, a_2,\d ...

随机推荐

  1. 在java中导出excel

    package com.huawei.controller; import java.io.File;import java.io.IOException;import java.util.HashM ...

  2. 【BZOJ3998】弦论 【后缀自动机】

    题意 给定一个长度为n的字符串,求他的第k小子串是什么. 分析 T=0的时候,这个题跟SPOJ-SUBLEX的做法一样,当T=1的时候,不同位置的子串算多个,那么初始化的时候d[u]=cnt[u],没 ...

  3. flume 转

    http://blog.csdn.net/xiao_jun_0820/article/details/38111305

  4. MySQL 基础常用命令

    一.启动与关闭 1.1 Linux下启动mysql 的命令: a. rpm包安装:service mysqld start b. 源码包安装:/usr/local/mysql/bin/mysqld_s ...

  5. poolmanager1.path-o-logical 很好的prefab preload工具

    http://docs.poolmanager1.path-o-logical.com/ 提高性能的不错选择

  6. 少一些套路,多一些真诚 ——groovy消灭表现层套路

      初次认识groovy是在2009年,当时看了Manning出版的<Groovy in Action 1st Edition>,对groovy这个语言的交互性shell,以及灵活的语法留 ...

  7. 行走于Swift的世界中(转)

    从Swift正式公布到现在,我基本一直在关注和摸索Swift.对于一门新语言来说,开荒阶段的探索自然是激动人心的,但是很多时候,资料的缺失和细节的隐藏也让人着实苦恼.最近几天的感受是,Swift 并不 ...

  8. Python之FTP传输-乾颐堂

    访问FTP,无非两件事情:upload和download,最近在项目中需要从ftp下载大量文件,然后我就试着去实验自己的ftp操作类,如下(PS:此段有问题,别复制使用,可以参考去试验自己的ftp类! ...

  9. diskpart setid value list

    ntfs : 07 / 17 显示/隐藏 fat32: 0C / 1C 显示/隐藏 0 空 24 NEC DOS 81 Minix / 旧 Linu bf Solaris 1 FAT12 27 隐藏的 ...

  10. Golang 之 Qrcode 二维码

    二维码大行其道,尤其 qrcode ,怎么能少了大golang 呢. follow me . 1.引用 go get github.com/skip2/go-qrcode 2.写 package ma ...