当前位置: 首页 > 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.jsqmd.com/news/71205/

相关文章:

  • Resources资源同步加载、异步加载、卸载
  • 新房全包装修怎么选?这 3 类高性价比公司帮你省心省钱(附 2025 口碑红榜) - 品牌测评鉴赏家
  • 无参和有参URL的定义
  • 线段的最少分组
  • 【Ubuntu】系统下VScode配置ESP-IDF插件esp-clang和Python 3报错问题
  • 新房装修不迷路!十大公司深度评测,盛世和家登顶榜首 - 品牌测评鉴赏家
  • windriver 第6章:使用DriverWizard
  • vue 中支持不定高的虚拟滚动的表格 vxe-table 的使用,动态高度虚拟列表高性能表格
  • windriver 第4章:PCI Express 概述
  • GROMACS 2025.4安装(非root用户)
  • MATLAB R2025a免费下载安装教程与激活教程超详细图文步骤(附安装包)
  • 解码string类——字符串处理
  • 新房装修公司大揭秘!一文教你避坑选好公司 - 品牌测评鉴赏家
  • 新手装修必看!第一次选对装修公司,省心攻略全解析 - 品牌测评鉴赏家
  • Docker Swarm 的负载均衡和平滑切换原理 - 实践
  • windriver 第3章: 安装WinDriver
  • 2025年推荐实力户外滑梯厂家飞友,以专业品质守护儿童欢乐时光 - 速递信息
  • 2025整装公司排行榜发布:十大整装品牌引领行业新趋势 - 速递信息
  • day3 Java基础3
  • 头歌MySQL——单表查询 - 详解
  • windriver 第2章: 了解设备驱动程序
  • 纯棉卫生巾推荐,4款热门产品深度横评,看完这篇再下单! - 速递信息
  • 2025年整装公司口碑推荐实力TOP榜|十大装修公司对比 - 速递信息
  • 2025年整装公司权威推荐榜:十大特色装修公司满足不同需求 - 速递信息
  • 2025整装公司排名榜!十强家装品牌核心优势对比 - 速递信息
  • 解决IDEA中项目目录的底色变黄
  • 2025年最新幼儿园教玩具品牌推荐,守护孩子成长——飞友用硬核筑牢成长防线 - 速递信息
  • 全屋整装公司品牌十强有哪些?2025排名与品牌解析 - 速递信息
  • 吐血整理!揭秘2025年新房装修公司哪家靠谱! - 品牌测评鉴赏家
  • 第五十九篇