• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

monui

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

2023沈阳D题题解

2023沈阳D题题解

​ 这题在VP的时候成功把我卡死了,原因是我一直没有想到用KMP去大力匹配,导致我的算法复杂度一直是O(n^2logn),然后就很典的T了。

​ VP完了之后想各种优化卡过去,但是都失败了,跑校园跑的时候突然想到怎么解了。

​ 现在我是这样看待这个问题的,这个问题应该是可以被拆分成两个部分:

​ 1.从字符串a中找到一个连续子串,在一侧补上之后可以满足题目要求的条件

​ 2.在找到这个连续子串以后,在字符串b里面匹配,找有多少个字符串匹配。

​ 第一步可以通过观察规律得到,这里可以举一个例子:abcd...abcd

​ 观察这个字符串,我们发现从a到a之间显然是有一个,从b到a,从b到b之间显然各有一个,那么以此类推,我们发现我们要做的,其实就是枚举前缀的最后一个字母,然后在右侧找这个字母,并且dp得到这个字母的最大前缀长度(与前面枚举的下标前缀要匹配)。

​ 那么显然,可以通过if(s[i-1]==s[j-1]) lst[j]=lst[j-1]+1;来实现这个DP,值得注意的是,为了保证前后的前缀是一致的,与当前的枚举的字母不匹配的下标的lst都需要清零。

​ 第二步相对来说可能会更简单。

​ 我是这样构思的,把字符串a,枚举每一个下标为开端,最后一个下标为尾,这样拆分出n条链。

​ 然后考虑把字符串b和这n条链进行匹配,第一步中得到的有效字符串在这一步中需要提前加在链的节点上,然后创建next数组的时候考虑路径压缩把父亲节点的值都求和在当前节点。

​ 然后就是大力匹配求和,对每个字符串都做一遍就行了。

没有具体实现,因为上面的思路是我口嗨的,懒得写。

posted on 2024-11-20 15:57  monui  阅读(28)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3