题解:Luogu P4143 采集矿石

news/2025/10/20 22:09:44/文章来源:https://www.cnblogs.com/P2441M/p/19153799

题意

给定长度为 \(n\) 的字符串 \(s\) 和权值序列 \(v\)。求所有子串 \(s[l,r]\) 使得 \(s[l,r]\) 在所有子串去重后的字典序降序排名,恰好等于 \(v[l,r]\) 的区间和。\(1\leq n\leq 10^5\)

题解

注意到固定左端点 \(l\) 后,随着右端点 \(r\) 递增,\(s[l,r]\) 的字典序降序排名单调递减,\(v[l,r]\) 的区间和单调递增,因此每个 \(l\) 最多对应一个合法的 \(r\)。考虑对 \(v\) 的区间和和子串的排名的差值二分,找到第一个 \(\geq 0\)\(r\)。现在我们需要对一个子串 \(s[l,r]\),求出其在所有子串去重后的字典序降序排名。

考察怎样的子串 \(s[l',r']\)\(>s[l,r]\),要么 \(s[l,r]\)\(s[l',r']\) 的前缀,要么 \(s[l',r']\) 在 LCP 的后一位比 \(s[l,r]\) 对应位置要大。不难发现若 \(s[l',r']>s[l,r]\),则 \(s[l',r''](r'<r''\leq n)\) 也一定 \(>s[l,r]\),所以我们转而考虑所有合法的 \(s[l',r']\) 对应的后缀 \(suf_{l'}\) 的性质。

对于第一种 case,相当于固定了一段前缀,那么所有合法后缀的排名必然是一段连续区间 \([L,R]\)。对于第二种 case,我们发现这样的后缀的排名其实就是 \([R+1,n]\)。因为 \(suf_{rk_R}\) 是排名最大的以 \(s[l,r]\) 为前缀的后缀,那么对于 \(suf_{rk_{R+1}}\) 来说,一定是在一段 LCP 之后,比 \(s[l,r]\) 的对应位大,这就和第二个条件完全契合了。

所以,所有合法的 \(s[l',r']\) 一定是排名处于 \([L,n]\) 之中的后缀的一段前缀。因此 \(s[l,r]\) 的字典序降序排名,实际上就是排名处于 \([L,n]\) 之中的后缀的本质不同前缀个数,减去 \(r-l\)。注意减去 \(r-l\) 是因为我们会把 \(s[l,r]\) 的真前缀也算进去。套用经典结论,排名在 \([L,n]\) 中的后缀的本质不同前缀个数就是 \(\sum\limits_{i=L}^n(n-sa_i+1)-\sum\limits_{i=L+1}^nht_i\),容易预处理后缀和计算。

至于 \(L\),可以发现它就是最小的 \(i\),使得排名在 \([i,rk_l]\) 中的后缀的 LCP 长度 \(\geq r-l+1\),用 ST 表维护 \(ht\) 即可二分求出。

时间复杂度是 \(\mathcal{O}(n\log^2{n})\) 的。

代码

#include <bits/stdc++.h>using namespace std;#define lowbit(x) ((x) & -(x))
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5, LGN = 18;template<typename T> inline void chk_min(T &x, T y) { x = min(x, y); }
template<typename T> inline void chk_max(T &x, T y) { x = max(x, y); }int n, sz, val[N], pre[N], lg2[N], ans[N];
int sa[N], rk[N], trk[N << 1], id[N], pid[N], buc[N], ht[N];
ll suf1[N], suf2[N];
char s[N];struct ST {int f[LGN][N];inline void init() {for (int i = 1; i <= n; ++i) f[0][i] = ht[i];for (int i = 1; i <= lg2[n]; ++i) for (int j = 1; j <= n - (1 << i) + 1; ++j)f[i][j] = min(f[i - 1][j], f[i - 1][j + (1 << i - 1)]);}inline int query(int l, int r) {int k = lg2[r - l + 1];return min(f[k][l], f[k][r - (1 << k) + 1]);}
} st;inline void build() {int m = 26;for (int i = 1; i <= n; ++i) ++buc[rk[i] = s[i] - 'a' + 1];for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];for (int i = n; i; --i) sa[buc[rk[i]]--] = i;for (int w = 1, p = 0; p < n; w <<= 1, m = p) {p = 0;for (int i = n - w + 1; i <= n; ++i) id[++p] = i;for (int i = 1; i <= n; ++i) if (sa[i] > w) id[++p] = sa[i] - w;fill(buc + 1, buc + m + 1, 0);for (int i = 1; i <= n; ++i) ++buc[pid[i] = rk[id[i]]];for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];for (int i = n; i; --i) sa[buc[pid[i]]--] = id[i];p = 0, copy(rk + 1, rk + n + 1, trk + 1);for (int i = 1; i <= n; ++i) rk[sa[i]] = (trk[sa[i - 1]] == trk[sa[i]] && trk[sa[i - 1] + w] == trk[sa[i] + w]) ? p : ++p;}for (int i = 1, k = 0; i <= n; ++i) {if (k) --k;while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;ht[rk[i]] = k;}for (int i = n; i; --i) suf1[i] = suf1[i + 1] + sa[i], suf2[i] = suf2[i + 1] + ht[i];
}
inline int getl(int p, int len) {int l = 1, r = p;while (l < r) {int mid = l + r >> 1, v = mid == p ? len : st.query(mid + 1, p);v >= len ? r = mid : l = mid + 1;}return l;
}
inline ll rnk(int l, int r) {int L = getl(rk[l], r - l + 1);return (ll)(n - L + 1) * (n + 1) - suf1[L] - suf2[L + 1] - (r - l);
}int main() {ios::sync_with_stdio(0), cin.tie(0);cin >> s + 1, n = strlen(s + 1);for (int i = 1; i <= n; ++i) cin >> val[i], pre[i] = pre[i - 1] + val[i];for (int i = 2; i <= n; ++i) lg2[i] = lg2[i >> 1] + 1;build(), st.init();for (int i = 1; i <= n; ++i) {int l = i, r = n;while (l < r) {int mid = l + r >> 1;pre[mid] - pre[i - 1] - rnk(i, mid) >= 0 ? r = mid: l = mid + 1;}if (pre[l] - pre[i - 1] == rnk(i, l)) ans[i] = l, ++sz;}cout << sz << '\n';for (int i = 1; i <= n; ++i) if (ans[i]) cout << i << ' ' << ans[i] << '\n';return 0;
}

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

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

相关文章

从18w到1600w播放量,我的一点思考。

你好呀,我是歪歪。 前几天我想要巩固一下共识算法这个知识点。 (先声明,这篇文章不深入讨论共识算法本身) 于是我在 B 站大学上搜索了“共识算法”这个词:我还特意按照播放量排序了一下,准备先找个播放量高点的视…

扣一个细节问题

请看下这个uint bits = 0; for (int y = 0; y < 5; y++) {for (int x = 0; x < 4; x++)bits |= b[y][x] << (y * 4 + x);}上面的代码把一个[5][4]的byte数组用bits表示,该数组里的元素非0即1. 在经典的Th…

10.20java作业

10.20java作业1.2.3.4.5. 结果Parent: myValue = 10 Child: myValue = 20 Child: myValue = 20 Child: myValue = 20 Child: myValue = 21 第一行输出:new Parent() 创建父类对象,调用父类的 printValue 方法,输出父…

题解:Luogu P14175 【MX-X23-T5】向死存魏

题意 给定长度为 \(n\) 的序列 \(a\) 和值域 \(V\)。有 \(m\) 次操作:给定 \(l,r,x\),将 \(a[l,r]\) 中 \(=x\) 的数改为 \(0\)。 给定 \(x\),在序列末尾添加 \(x\)。 给定 \(l\),查询最小的 \(r\) 使得 \(a[l,r]\…

软工第三次作业————结对作业

软工第三次作业————结对作业软工第三次作业--结对作业 软工第三次作业结对作业——实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)项目作业 实现一个自动生成小学四则运算题目的…

Spring 常见注解

目录🧐 @Configuration 和 @Import 的核心区别详细解释1. @Configuration (配置类)2. @Import (引入)参考资料 🧐 @Configuration 和 @Import 的核心区别特性 @Configuration @Import主要目的 标记一个类是 Java 配…

题解:AtCoder ARC208C Mod of XOR

题意 给定 \(C,X\),构造一个 \(n(1\leq n<2^{60})\) 使得 \((n\oplus C)\bmod{n}=X\),或报告无解。多测,\(1\leq T\leq 2\times 10^5\),\(1\leq C,X<2^{30}\)。 题解 神人构造题。 显然要有 \(n>X\)。不妨…

题解:Luogu P6898 [ICPC 2014 WF] Metal Processing Plant

题意 给定 \(n\),对于每个 \(1\leq i,j\leq n\),给出 \(d(i,j)\)。对于集合 \(S\),定义 \(D(S)=\max\limits_{i,j\in S}d(i,j)\)。将 \(\{1,2,\cdots,n\}\) 划分为两个集合 \(A,B\),最小化 \(D(A)+D(B)\)。\(1\leq…

32-腾讯IM接入资料和定价

腾讯IM接入资料和定价信息 一、产品概述 腾讯云即时通信IM(Instant Messaging)是腾讯提供的企业级即时通讯服务,支持多种平台接入,包括Android、iOS、Web和小程序等。 二、定价信息 1. 基础服务资费体验版: 提供完…

题解:AtCoder ARC207A Affinity for Artifacts

题意 给定长度为 \(n\) 的序列 \(a\) 和一个数 \(X\),求有多少种 \(a\) 的重排 \(b\) 使得 \(\sum\limits_{i=1}^n\max(b_i-i+1,0)\leq X\)。\(1\leq n\leq 100\),\(1\leq a_i,X\leq 10^9\)。 题解 你说得对,但我怎…

题解:Luogu P9260 [PA 2022] Miny

题意 给定一棵 \(n\) 个点的树,第 \(i\) 条边 \((a_i,b_i)\) 有边权 \(c_i\),第 \(i\) 个点有一个爆炸半径 \(r_i\)。当一个点被引爆时,所有在该点爆炸半径范围内的点也会被引爆,这些新的被引爆的点也可能继续引爆…

题解:Luogu P13544 [OOI 2022] Serious Business

题意 给定一个 \(3\times n\) 的网格,每个格子 \((i,j)\) 内有一个数 \(a_{i,j}\)。一个人初始分数为 \(0\),在位置 \((1,1)\) 处,每次可以向右或向下走一格,目标是到达 \((3,n)\)。当走到格子 \((i,j)\) 时,这个…

题解:Luogu P14254 分割(divide)

题意 给定一棵 \(n\) 个点的树,设根节点 \(1\) 的深度为 \(1\)。给定 \(k\),求有多少从树中选出 \(k\) 个两两不同的节点,组成有序序列 \(b_1,\cdots,b_k\) 的方案,使得:对于每个 \(1\leq i<k\),\(1<d_{b_…

31_创蓝短信接入资料和定价

创蓝短信接入资料和定价 公司简介 创蓝云智为企业提供短信、语音外呼、闪验、号码检测、实名认证等通讯类产品,致力于让企业更高效高质量的获得用户及触达用户。 产品类型通知短信 会员营销短信 国际营销短信 验证码短…

构造单

题目来源 取模下序列构造 是否存在 \(3\) 个长度为 \(n\) 的 \([0,n)\) 的排列 \(a,b,c\),使得 \(a_i+b_i=c_i\mod n\) 遇到取模考虑奇偶性,不要像太复杂,考虑 \(n\) 为奇数的时候直接 \(a=b=~0,1,2,3,4,…\),\(c=…

02.Python百行代码实现抽奖系统

02.Python百行代码实现抽奖系统 ------------------------------------------------ 执行后——————————————————————————————————————————————————————————…

[笔记]高斯消元

高斯消元法是求解线性方程组的经典算法。 内容 求解如下的线性方程组(P3389 【模板】高斯消元法): \[\begin{cases} a_{1,1}x_1+a_{1,2}x_2+\dots+a_{1,n}x_n=b_1\\ a_{2,1}x_1+a_{2,2}x_2+\dots+a_{2,n}x_n=b_2\\ …

[SSH] scp:基于 SSH 的安全文件传输

[SSH] scp:基于 SSH 的安全文件传输$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");目录01 简介02 操作2.1 本地发送到远程2.2 从远程下载2.3 主机之间复制…

CSP-S 35

10.2010.20 神秘%你赛,rk1 170 ,你管这叫CSP-S? t1 赛时狂写t1 ,想了半天想出来个神秘做法,时间复杂度不会证但应该是对的,写完本地大阳历1.2s 感觉应该没啥大问题,结果空间炸了,最后2h写的代码和暴力分一样多 …

题解:P11662 [JOI 2025 Final] 方格染色 / Grid Coloring

题目传送门 是一道黄题 这里提供一种 \(O(n\log n)\) 的做法\(\mathscr{PART\ \ ONE}\)我们在手%的时候不难发现(注意力有点也不惊人) 虽然第一列和第一行 不保证有序 但是因为这里的前缀$\ max\ $性质保证了第二列和…