{LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度 题解

news/2025/3/10 18:57:22/文章来源:https://www.cnblogs.com/Rock-N-Roll/p/18672755

\(\text{LOJ \#6041. 「雅礼集训 2017 Day7」事情的相似度 题解}\)

解法一

由 parent 树的性质得到,前缀 \(s_i,s_j\) 的最长公共后缀实质上就是 \(i,j\) 在 SAM 中的 \(\operatorname{LCA}\) 在 SAM 中的 \(\operatorname{len}\)。让我们考虑如何处理 \((l,r)\) 区间内的询问。直接考虑求 \((l,r)\) 的贡献是困难的,不妨转变思路,求每个点对于子树内的贡献。对于一个点 \(x\),我们可以容易地用启发式合并来合并出子树内所有的节点。考虑加入子树 \(y\) 的贡献后怎么做:不难发现对于一个 \(a\),我们只需要统计离 \(a\) 最近的 \(p,q(p\le a,a\le q)\)。这样我们在合并的时候顺便用 std::set 可以求出。由启发式合并的复杂度可以知道,这样做的总复杂度是 \(O(n\log^2n)\)。 然后我们得到了 \(O(n\log n)\) 个贡献三元组 \((l,r,w)\)\(m\) 个询问 \((l,r)\),实际上是一个二维偏序问题,排序后树状数组维护即可。总的时间复杂度是 \(O(n\log^2n)\) 的。

代码:

#include <bits/stdc++.h>
#define N 2000005
#define M 2
using namespace std;
int n, m;
char s[N];
int tot = 1, lst = 1;
struct SAM {int len, fa;int s[M];
} sam[N];
set<int>st[N];
void insert(int c, int x) {int p = lst, np = lst = ++tot;sam[np].len = sam[p].len + 1;for (; !sam[p].s[c]; p = sam[p].fa) sam[p].s[c] = np;if (!p) sam[np].fa = 1;else {int q = sam[p].s[c];if (sam[q].len == sam[p].len + 1) sam[np].fa = q;else {int nq = ++tot;sam[nq] = sam[q], sam[nq].len = sam[p].len + 1;sam[np].fa = sam[q].fa = nq;for (; sam[p].s[c] == q; p = sam[p].fa) sam[p].s[c] = nq; }}st[lst].insert(x);
}vector<int>v[N];
struct node {int r, vl;
};
vector<node>upd[N], que[N];void dfs(int x) {for (auto y : v[x]) {dfs(y);if (st[x].size() < st[y].size()) swap(st[x], st[y]);st[x].insert(-1e9), st[x].insert(1e9);for (auto i : st[y]) {auto it = --st[x].upper_bound(i);if ((*it) != -1e9) upd[*it].push_back({i, sam[x].len});it = st[x].lower_bound(i);if ((*it) != 1e9) upd[i].push_back({*it, sam[x].len});}st[x].erase(-1e9), st[x].erase(1e9);st[x].insert(st[y].begin(), st[y].end());st[y].clear();}
}int lbt(int x) {return x & -x;
}
int tr[N];
void add(int x, int vl) {while (x <= n) tr[x] = max(tr[x], vl), x += lbt(x); 
}
int ask(int x) {int ans = 0;while (x) ans = max(tr[x], ans), x -= lbt(x);return ans;
}int ans[N];int main() {ios::sync_with_stdio(0);cin.tie(0);cin >> n >> m;cin >> s;for (int i = 0; i < n; i++) insert(s[i] - '0', i + 1);for (int i = 2; i <= tot; i++) v[sam[i].fa].push_back(i);dfs(1);for (int i = 1; i <= m; i++) {int l, r;cin >> l >> r;que[l].push_back({r, i});}for (int i = n; i >= 1; i--) {for (auto p : upd[i]) add(p.r, p.vl);for (auto p : que[i]) ans[p.vl] = ask(p.r);}for (int i = 1; i <= m; i++) cout << ans[i] << "\n";return 0;
}

解法二

实际上本题是信息搜集题,我将给出符合题目描述的图片,相信大家能推断出本题真正的答案。

picture1

picture2

picture3

picture4

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

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

相关文章

解决Hyper-V保留端口导致各种端口占用报错的问题

0.有时候在本地启用一个服务比如MySQL服务,或者在启用IDEA的调试的时候,或者在本地启用一个监听端口的时候可能会出现监听失败的情况,经过查找之后会发现并没有应用占用相应的端口。 1.经过查找发现其实是在启用了Hyper-V之后系统会保留一些端口,这些端口如果包含了你应用要…

D. Madoka and The Corruption Scheme -- (贪心,组合数学,构造)

题目链接:Problem - D - Codeforces 题目大意: 一共n轮比赛,有\(2^n\)个参赛者,第\(i\)轮有\(2^{n - i}\) 场比赛,Madoka能安排第一局的比赛,她想让最后的赢家编号更小,主办方最多有k次操作,能修改任意每一场比赛的获胜情况,可以让最终赢家编号更 大,求Madoka在主办方…

PHP语法基础

PHP语法基础php文档拓展名是.phpphp文件通常包含html标签以及一些php脚本运行代码 ,注意:html js css可以在php文件执行但是,php不能在html js css在php文件执行php语法用;结尾 <!DOCTYPE html> <html> <body> <h1>我的第一张php页面><h1>…

本地打包docker images并上传到服务器.250115

情景: 服务器docker Pull 拉不下来 docker pull easzlab/kubeasz-k8s-bin:v1.31.2 Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 2025-01-14 17:06:35 [ez…

包豪斯学院

包豪斯学院(Bauhaus)是20世纪最具影响力的艺术与设计学府之一,创立于1919年,由建筑师沃尔特格罗皮乌斯(Walter Gropius)在德国魏玛建立。作为现代主义设计的先锋,包豪斯不仅在建筑、工艺、艺术和设计等领域开创了新局面,其设计理念更是深刻影响了全球的艺术与工业生产方…

主机PHP版本过低导致网页无法正常运行的解决办法

问题描述: 用户发现其主机上的PHP版本过低,导致某些功能无法正常使用,影响了网站的整体性能。此外,用户询问是否可以通过升级主机获得免费域名赠品,以及数据库空间不足的问题。 解决方案: 针对您遇到的主机PHP版本过低的问题,这里提供一些解决方案和建议,帮助您顺利升级…

如何解决网站在多台电脑上打开速度慢的问题

问题描述: 用户反馈,其家庭和单位的电脑在访问某个特定域名时速度非常慢,但手机端访问速度正常。此外,用户还提到服务器存在大量漏洞,担心网站安全问题,并询问如何处理这些漏洞。 解决方案: 针对您提到的家庭和单位电脑访问域名速度慢的问题,我们首先需要排查以下几个方…

如何处理宝塔面板升级失败及账户密码重置?

针对您遇到的宝塔面板升级失败以及账户密码重置的问题,我们将为您提供详细的解决方案。 宝塔面板升级失败 宝塔面板升级失败可能是由多种原因引起的,常见的原因包括但不限于以下几点:网络连接不稳定:在升级过程中,如果网络连接中断或者速度过慢,可能会导致下载更新包失败…

升级建站助手后原有站点无法访问怎么办?

关于您提到的升级建站助手后原有站点无法访问的问题,我们将为您提供详细的解决方案。 分析问题原因 首先,我们需要明确几个关键点来帮助分析问题的原因:建站助手与宝塔面板的关系:建站助手和宝塔面板都是用于管理和部署网站的应用程序,但它们之间可能存在功能上的重叠或冲…

补充

补充重要知识 目录补充重要知识防脱发神器颜色的alpha通道尺寸的百分比最大最小宽高什么时候使用绝对定位fixed和absolute的区别伪类选择器contenteditable属性table 元素 防脱发神器 一图胜千言使用border-box控制尺寸更加直观,因此,很多网站都会加入下面的代码 * {margin: …

如何修改数据库密码?

当您需要修改数据库密码时,确保操作正确且不影响现有应用是非常重要的。以下是详细的步骤说明和注意事项,帮助您顺利完成数据库密码的修改:备份现有数据: 在进行任何修改操作之前,强烈建议您先对当前数据库进行完整备份。这不仅可以防止误操作导致的数据丢失,还能为后续恢…