重做 CF906E Reverses

news/2025/2/10 8:36:18/文章来源:https://www.cnblogs.com/LUHCUH/p/18707056
  • 不是,JJ 怎么退役了,悲。
  • 嗯,先有

\[dp_{r}=\min_{l=1}^r[s(l,r)\text{是回文串,且长度不为 2}]dp_{l-1}+1 \]

  • 总复杂度就 \(n^2\),考虑优化
  • 然后有引理说,一个字符串的所有 border 构成 \(\log n\) 个等差数列
  • 我们考虑什么样的点能够转移到 \(dp_i\)

  • 尝试借助 \(log\) 段,成段转移,具体的,正如上图,右侧所示,我们把每一段的 \(dp\) 值的最大值存到蓝色点,即段的最长节点,嗯,对,紫色存到蓝色里。至于为什么是这样,之后解释。
  • 由于回文自动机只记录回文串,并不记录回文串的位置,所以我们考虑 log 段上的一段,在加了若干个字符的变化,如图。

  • 当某一时刻,我们加了一段绿色的段,而在回文自动机上有大量重复的节点。首先我们有 红色括号里的等于紫色括号里的。所以我们粉色框所代表的上一个转移点,与紫色括号的转移点是相同的。
  • 紫色线条表示的是两个段字符串相等(不是 好像没啥用)
  • 之后注意,我们把什么样的算作一段,蓝色块开头,带着一堆紫色块。
  • 所以与之前的转移点一一对应,少的不是最底下的蓝色块(我卡在这半天)。而是上面的紫色块。蓝色算作下一段的开头。所以我们补上的是 \(i-diff-slink\) 的位置

  • 之后,感性理解一件事情,log 段中,每一段的开头在原串中开头在回文自动机中存的值一定不是位置 \(x\) 而是紧接着的前一个位置 \(y\)
  • 而次小串 \(x'\) 上一次出现的位置是 \(x''\) 而不是 \(y'\)。所以我们取之前的 \(x''\) 在回文自动机里的值来更新当前位置 \(x\) 是没有问题的,因为必定是紧接着的前一个。也是为什么把总贡献存到最大位置的原因,因为可以从小逐步更新,保证继承的一定是前一段。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 500050;
char s1[N], s2[N], s[N << 1];
struct Node { int trans[26], fail, len, diff, slink; }tr[N << 1]; int idx = 1;
int Fail(int x, int i)
{while (s[i] != s[i - tr[x].len - 1])x = tr[x].fail;return x;
}
int f[N << 1], g[N << 1], ans[N << 1];
void insert(int i)
{static int edp = 1;int pos = Fail(edp, i);if (!tr[pos].trans[s[i] - 'a']){idx++;tr[idx].fail = tr[Fail(tr[pos].fail, i)].trans[s[i] - 'a'];tr[pos].trans[s[i] - 'a'] = idx;tr[idx].len = tr[pos].len + 2;tr[idx].diff = tr[idx].len - tr[tr[idx].fail].len;tr[idx].slink = (tr[idx].diff ^ tr[tr[idx].fail].diff) ? tr[idx].fail : tr[tr[idx].fail].slink;//printf("New: %d %d %d %d\n", tr[idx].fail, tr[idx].len, tr[idx].diff, tr[idx].slink);}edp = tr[pos].trans[s[i] - 'a'];if (i % 2 == 0 && s[i] == s[i - 1] && f[i] > f[i - 2])f[i] = f[i - 2], ans[i] = i - 2;for (int k = edp; k; k = tr[k].slink){g[k] = i - tr[tr[k].slink].len - tr[k].diff;if (tr[tr[k].fail].diff == tr[k].diff && f[g[k]] > f[g[tr[k].fail]])g[k] = g[tr[k].fail];if (i % 2 == 0 && f[g[k]] + 1 < f[i]) f[i] = f[g[k]] + 1, ans[i] = g[k];}
}
int main()
{memset(f, 0x3f, sizeof f);tr[0].fail = 1; tr[1].len = -1;scanf("%s%s", s1 + 1, s2 + 1);int n = strlen(s1 + 1);for (int i = 1; i <= n; i++)s[(i << 1) - 1] = s1[i], s[i << 1] = s2[i];n = n << 1; s[n + 1] = '\0';f[0] = 0;for (int i = 1; i <= n; i++)insert(i);if (f[n] > 1e9)puts("-1");else{printf("%d\n", f[n]);for (int i = n; i >= 1; i = ans[i])if (i - ans[i] != 2)printf("%d %d\n", ans[i] / 2 + 1, i / 2);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881536.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zerto 10.0 Update 6 下载 - 适用于本地、混合和多云环境的灾难恢复和数据保护

Zerto 10.0 Update 6 下载 - 适用于本地、混合和多云环境的灾难恢复和数据保护Zerto 10.0 U6 - 适用于本地、混合和多云环境的灾难恢复和数据保护 勒索软件防护、灾难恢复和多云移动性的统一解决方案 请访问原文链接:https://sysin.org/blog/zerto-10/ 查看最新版。原创作品,…

OpenWrt 24.10 OVF:在 ESXi 8.0、Fusion 13 和 Workstation 17 上运行 OpenWrt 的简单方法

OpenWrt 24.10 OVF:在 ESXi 8.0、Fusion 13 和 Workstation 17 上运行 OpenWrt 的简单方法OpenWrt 24.10 OVF:在 ESXi 8.0、Fusion 13 和 Workstation 17 上运行 OpenWrt 的简单方法 OpenWrt 24.10.0 x86_64 OVF 请访问原文链接:https://sysin.org/blog/openwrt-ovf/ 查看最…

SQL Server 2022新功能:将数据库备份到S3兼容的对象存储

SQL Server 2022新功能:将数据库备份到S3兼容的对象存储 本文介绍将S3兼容的对象存储用作数据库备份目标所需的概念、要求和组件。 数据库备份和恢复功能在概念上类似于使用SQL Server备份到Azure Blob存储的URL作为备份设备类型。 要注意的是,不只是amazon S3对象存储,只要…

护眼神器!LightBulb电脑屏幕护眼软件,你值得拥有!

点击上方蓝字关注我 前言 LightBulb是一个免费的护眼软件,它可以帮助我们在晚上或长时间看电脑屏幕时,减少眼睛的不舒服和疲劳。这个软件会随着一天时间的推移,自动调整电脑屏幕的颜色。比如,在白天,它会让屏幕颜色更偏向冷蓝色,就像阳光下的颜色;到了晚上,它会让屏幕颜…

【JWT安全】攻防指南全面梳理

一、简单介绍 JWT(JSON Web Token)是一种用于身份认证和授权的开放标准,它通过在网络应用间传递被加密的JSON数据来安全地传输信息使得身份验证和授权变得更加简单和安全,JWT对于渗透测试人员而言可能是一种非常吸引人的攻击途径,因为它们不仅是让你获得无限访问权限的关键而…

【CodeForces训练记录】Codeforces Round 1003 (Div. 4)

训练情况赛后反思 题面读的有点疑惑,怀疑自己阅读理解不大行了,简单题狂WA,C2二分调半天没出,水平严重退步 A题 最后两个字母 us 换成 i点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;void solve(){string s;…

[流程图/技术调研] drawio : 流程图绘制工具

引言 流程图绘制工具: draw.io 简介urlhttps://www.drawio.com/ (官网首页) https://github.com/jgraph/drawio (github)【官网简介】 drawio 这个项目,是一个可配置的图表/白板可视化应用程序。drawio 是由 JGraph Ltd 和 draw AG 共同拥有和开发的。 在运行这个项目的同时,…

国家中小学智慧教育平台新教材及音频下载神器

点击上方蓝字关注我 前言 国家中小学智慧教育平台是一个专门给老师、孩子们提供学习资源的网站,上面有很多专业的教学视频、课件和教材。不过,这些学习资料都只能在网上看,如果没有网络就连不上了。 而这个下载器的作用就像是一个“搬运工”,它可以把这些网上的视频、课件和…

【牛客训练记录】牛客周赛 Round 80

训练情况赛后反思 玩了一两天发现自己水平直接下降一个档次,简单的C题模拟没写出来 A题 直接判断剩下还能放几个棋子,如果小于零就无法放置,否则直接输出即可点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;voi…

【蓝桥训练记录】第 26 场 蓝桥入门赛

训练情况赛后反思 唐完了,二分没看出来 A题 字母排序点击查看代码 #include <iostream> using namespace std; int main() {cout<<"aekns";return 0; }B题 统计两个字符串中 01 的数量,异或找两个不同的数字的出现次数取最小值,再求和即可点击查看代码…

手把手教你一招永久解决DeepSeek服务器繁忙!

前几天A梦分享过DeepSeek的三种使用方式:移动应用APP、网页版本和本地部署。由于DeepSeek的用户数量庞大,导致请求频次较高,用户常常会遇到"服务器繁忙,请稍后重试"的提示。而选择本地部署则可以避免这种问题,并且支持离线使用。正因如此,官方推荐用户选择本地…