Ginger的操作序列I

  众所周知,Ginger是一位实力强劲的算法竞赛选手,擅长各种各样的算法,一切问题对于 Ginger来说都游刃有余。这一天Ginger发现了一个有趣的题目,题目的内容是这样的:
  有n个算法,Ginger每次选择一个区间[l,r],学习这个区间里的所有算法,但是每个算法只能学习一次(因为Ginger一次就学会了),所以Ginger想知道每次他能新学会几种算法。这个问题实在太简单了Ginger微微一笑就做出了这道题,但是Ginger决定拿这道题考考你。
输入格式:
  第一行两个数 n,m(1n,m2×106)n代表n种算法,m代表Ginger的操作次数。接下来m行,每行两个数 l,r(1lrn),代表Ginger学会 [l,r] 这个区间的算法。

思路:
  看完题目可以知道,这道题只需要执行区间覆盖操作和区间查询操作,很自然的就可以想到珂朵莉树这么一个很好用的数据结构,但是交上去TLE了,再看看数据范围2106,也就是说如果卡的很死的话,单次区间查询的操作就会被卡成O(n)级别的,那么就需要去换一个线性的做法。
  因为这个题目里面只有0,1两种状态的集合,所以我们可以考虑用DSU将已经学过了的题目合并在一个集合里面,这样做就是线性了每个点只会被访问一次。在每一次询问,我们都让当前节点的父节点和他后一个节点的父节点合并为一个集合,这样当我们重新访问一段已经访问过的区间的时候,就可以直接跳到最近的一个没有访问过的节点。

int main() { std::cin.tie(nullptr)->sync_with_stdio(false); int n, q; std::cin >> n >> q; DSU uf(n + 2); for (int i = 0; i < q; i ++ ) { int l, r; std::cin >> l >> r; int fl = uf.leader(l); int ans = 0; for (int j = fl; j <= r;) { ans ++; uf.f[j] = j + 1; j = uf.leader(j + 1); } std::cout << ans << "\n"; } return 0 ^ 0; }

__EOF__

本文作者HoneyGrey
本文链接https://www.cnblogs.com/Haven-/p/16579181.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   浅渊  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示