当前位置: 首页 > news >正文

DSU on array

DSU on array 是一种把并查集用于一维数组上的技巧,用来维护数组中下一处未处理的位置。简单的说,如果某个位置 \(i\) 已被处理,我们希望下一次访问它时自动跳转到下一个没有被处理的位置 \(j\)

1 - 适用场景

场景 1 区间赋值(未被赋值的位置)

  • \([l, r]\) 内未被处理过的点赋值(染色、标记、填数)

场景 2 区间删除

  • 删除 \([l, r]\) 中所有仍存在的点

  • 后续查询要跳过已经删除的节点

场景 3 击败 / 消灭模型

  • 如:winner 在区间内存活,其他人都被淘汰

场景 4 寻找区间内下一位置

  • 寻找区间内第一个“未覆盖”位置

  • 区间被划分、覆盖后需要跳过已覆盖点

场景 5 离线模拟多次区间处理

  • 处理区间顺序已知,适合用 DSU 做快速跳跃

2 - 常用模板

初始化及函数:

// 初始化 fa[i] = i;
vector<int> fa(n + 2);
iota(fa.begin(), fa.end(), 0);// 找到 x 的下一个还未处理的位置。
function<int(int)> find = [&](int x) {while (x != fa[x]) x = fa[x] = fa[fa[x]];return x;
};// 删除该位置,即将 fa[x] 设为下一个还未处理的位置。
function<void(int)> erase = [&](int x) {fa[x] = find(x + 1);
};

遍历方式:

int cur = find(l);
while (cur <= r) {/* 代码块 */erase(cur);cur = find(cur);
}

3 - 例题 - CF356A

题目大意:

\(n\) 个从 \(1-n\) 编号的骑士,现在要在他们之间进行总共 \(m\) 场比赛。第 \(i\) 场比赛会在 \([l_i, r_i]\) 编号的骑士之间进行,并决出一位胜者 \(x_i\),其他骑士会出局并无法参加接下来的比赛。最后留下的骑士就是比赛的最终胜者。请你输出比赛结束后每一位骑士都被哪一位骑士击败了。

思路:

首先思考朴素解法,每次比赛的时候我们会遍历 \([l_i, r_i]\) 并处理此前没有被击败的骑士,这种解法复杂度为 \(O(n^2)\) 明显无法通过大数据范围。

而题意明显符合 DSU on array 的击败模型,因此我们考虑使用 DSU 来跳过每回合被击败的骑士,此时时间复杂度优化至 \(O((n + m) \alpha (n))\),其中 \(n\) 为骑士数量,\(m\) 为询问次数。因为 \(\alpha (n)\) 为阿克曼反函数,因此整体时间复杂度近似 \(O(n + m)\)。具体实现参考代码。

code:

#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define i64 long longint main() {ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);int n, m;cin >> n >> m;vector<int> fa(n + 2);iota(fa.begin(), fa.end(), 0);function<int(int)> find = [&](int x) {while (x != fa[x]) x = fa[x] = fa[fa[x]];return x;};function<void(int)> erase = [&](int x) {fa[x] = find(x + 1);};vector<int> ans(n + 1);for (int i = 1; i <= m; i ++ ) {int l, r, winner;cin >> l >> r >> winner;if (l > r) swap(l, r);for (int j = find(l); j <= r; j = find(j) /* 跳转至下一个未处理的位置 */) {// 跳过 winnerif (j == winner) {j = find(j + 1);continue;}// 赋值答案并删除 jans[j] = winner;erase(j);}}for (int i = 1; i <= n; i ++ ) {cout << ans[i] << ' ';}
}
http://www.zskr.cn/news/81747.html

相关文章:

  • 吐血整理!新房全包装修,性价比之王大盘点 - 品牌测评鉴赏家
  • Resources资源同步加载、异步加载、卸载
  • windriver 第6章:使用DriverWizard
  • MATLAB R2025a免费下载安装教程与激活教程超详细图文步骤(附安装包)
  • 新房装修公司大揭秘!一文教你避坑选好公司 - 品牌测评鉴赏家
  • 2025整装公司排行榜发布:十大整装品牌引领行业新趋势 - 速递信息
  • 头歌MySQL——单表查询 - 详解
  • 2025年整装公司口碑推荐实力TOP榜|十大装修公司对比 - 速递信息
  • Maven 用户的 Gradle 迁移与精通手册 - 指南
  • AI元人文构想:论当代论文与LLM
  • 引脚定义
  • 任意地址写format_string_level1题后感basectf
  • scheme区间算术
  • HashMap
  • CDQ 分治
  • day3 Java基础2
  • 2025年12月成都软件开发公司最新推荐,crm系统定制,管理系统,物联网,运维管理系统软件开发公司选择指南 - 品牌鉴赏师
  • PPT: Pre-trained Prompt Tuning - 预训练提示调优详解 - 教程
  • 某中心在EMNLP 2024的50余篇AI论文技术纵览
  • 常见八大排序算法介绍(冒泡排序、插入排序、归并排序、计数排序、选择排序、快速排序、堆排序、希尔排序)
  • 你的接口很好,但在使用者眼里,它可能只是个打不开的黑盒
  • 完整教程:Prefix-Tuning:大语言模型的高效微调新范式
  • 钉钉告警部署【prometheus-webhook-dingtalk】
  • day3 Java基础
  • Typora最后的免费版本
  • linux vrf icmp reply /vrf icmp 响应错误消息
  • python —— 满二叉树的构建
  • 2025 最新箱包五金配件厂家 TOP5 评测!高端定制 + 全链服务权威榜单发布,技术赋能重构箱包五金生态 - 全局中转站
  • 1010000
  • 1001101