\(C_n^m\)的typora,点了一下启用源代码模式就把我已经写好的博客弄没了,就给我留个标题,自动保存也只给我保存了个标题……\(C_n^m\),wdnmd

- Time limit
1000 ms

  • Memory limit

    262144 kB

解题思路

KMP

打比赛的时候愣是想不到怎么用KMP,总想着如果用kmp,那么每次合并都要更新nxt数组,会被卡到n方,就是想不到老字符串不用每次都全体参与KMP,每次只需要把老字符串后面那段拿出来判断就行了……还想着是不是要用啥我现在还不会的高级玩意……对KMP的理解只停留在做最裸的那种板题……

KMP有两种玩法,目的都是在合并老字符串(之前合并的结果)和新字符串(最新读入的)的时候找出可以被合并的长度,然后就能把新字符串后面那截不能合并的接到老字符串后面。边写边骂typora。由于合并的时候,老字符串和新字符串重复的长度小于等于新字符串的长度,所以处理的时候都截取老字符串后面和新字符串等长的一截(如果新字符串比老字符串长,那么就选整个老字符串)

一种是官方题解的思路——先把新字符串放前面,把“老字符串的后面一截”放后面,然后对于这个新接的合体字符串跑一遍KMP,求出nxt数组,以便找到最长的border(这个是nxt数组的定义了),这个就是可以合并的长度了,当然这个值要是大于了读入的新字符串或者之前合并出来的老字符串的长度,就要取“最长border长度、读入的新字符串的长度、之前合并的老字符串的长度”这三者的最小值,因为合并两个字符串最多就是一个把另一个吞并了,长度不会小于两个字符串中的任意一个。

另一种思路来自这篇博客——每次读入新字符串以后,把新字符串作为模式串,把老字符串的后面那截作为文本串。然后就跑几乎是裸的KMP了——先求出新字符串的nxt数组,然后用新字符串去匹配文本串(老字符串的后面那截),如果匹配的时候文本串的指针跑到头了,那么现在这个模式串指针指向的字符就是合并后新字符串贡献的第一个字符。如果文本串指针还没跑到头,模式串指针跑到头了,那么说明新字符串合并上去以后就啥都不剩了,完全被老字符串吞并了。这两种情况,都可以返回模式串指针的位置。这个位置一直到新字符串末尾这段就是要新加的了。

另外,KMP各种写法导致的指针加一减一的问题,微调一下就好了。

哈希

快速求几个子串的哈希值的方法,貌似NOI2016、2017连着考了两年,其他时候也用得不少,但我至今还没填坑……再次留坑。扔个链接先跑了。

源代码

#include<cstdio>
#include<cstring>
#include<algorithm>
const int MAXN=1e6+5;
int n;
char a[MAXN],b[MAXN];
int nxt[MAXN];
int lena,lenb;
int kmp(int st)//传入模式串的匹配起点
{
int i,j;
nxt[0]=-1;
for(i=1,j=-1;i<lenb;i++)
{
while(~j&&b[i]!=b[j+1]) j=nxt[j];
if(b[i]==b[j+1]) j++;
nxt[i]=j;
}
// for(int x=0;x<lenb;x++) printf("%d ",nxt[x]);
// puts(b);
for(i=st,j=-1;i<lena;i++)
{
while(~j&&b[j+1]!=a[i]) j=nxt[j];
if(a[i]==b[j+1]) j++;
if(j==lenb-1) return lenb;
}
return j+1;
} int main()
{
//freopen("test.in","r",stdin);
scanf("%d%s",&n,a);
lena=strlen(a);
n--;
while(n--)
{
scanf("%s",b);
lenb=strlen(b);
int temp=kmp(std::max(0,lena-lenb));
// printf("%d\n",temp);
for(int i=temp;i<lenb;i++)
a[lena++]=b[i];
}
a[lena]=0;
puts(a);
return 0;
}

这场CF的F题听说是什么基环树,太难了(借口),留坑,不补了

最新文章

  1. Codeforces Round #364 (Div. 2)
  2. js获取div相对屏幕的坐标位置
  3. [Voice communications] 让音乐响起来
  4. LRU Cache [LeetCode]
  5. C#数据库绑定
  6. 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹
  7. mysql在高内存、IO利用率上的几个优化点 (sync+fsync) 猎豹移动技术博客
  8. flask-mail发送QQ邮件代码示例(亲测可行)
  9. 在PHP中连接数据库的八大步骤
  10. 在webstorm开发微信小程序之使用阿里自定义字体图标
  11. jsp视频如何播放
  12. web api HttpResponseMessage的简单使用
  13. Flask请求流程超清大图
  14. List集合2-LinkedList
  15. JDBC ---获取数据字段 -- 转成map
  16. Window和document的区别
  17. Zuul Pre和Post过滤器
  18. go语言处理文件上传和多个文件上传
  19. 玩转Hook——Android权限管理功能探讨(一)
  20. linux rename命令批量修改文件名

热门文章

  1. Akka系列(九):Akka分布式之Akka Remote
  2. vue--过滤器(私有,全局)
  3. python GIL全局解释器锁与互斥锁 目录
  4. javaScript中==和===对数组、对象的判断是它们是否同一个实例对象
  5. (5.2.2)配置服务器参数——dbcc跟踪标记(trace)
  6. 小记----采集之Xpath
  7. MacOS 下文件读取问题
  8. $Prufer$序列
  9. npm切换淘宝镜像源
  10. python实现策略模式