线段树分治+可撤销并查集 学习笔记

题目一般是给你边或者点的出现时间区间[Li,Ri],问你在某些时间里1能访问到的点或者点的数量。

先考虑暴力的思路,就是对于一个具体的时间节点,我们去暴力地得知当前边/点是否出现,并且跑图查看是否联通。

由于一个具体的时间节点前后联通情况大致相似,我们考虑是否可以在继承前一个时间节点的情况下,只是局部改变一些点和边的情况?

因为我们是去查看图的联通,免不了使用并查集。当一条边加入进来好处理,但如果删除呢?

线段树分治+可撤销并查集就是用来解决此类问题。

将每条边的时间线段用线段树来分开,每条线段只会分成log个,并且可以保证分完后的所有线段不相交。我们以时间为轴,记录线段树上每个时间区间覆盖的边,然后对线段树进行 DFS,进入一个区间就在并查集里加入这个区间的所有边,离开时再撤销这些边。

可撤销并查集,实际上就是一个用一个栈,在撤销时把最近加入栈中的边回滚掉。回滚的操作就是将原来的一棵树砍下一个树枝,变成两棵树。(那么此时我们就不可以用原来的路径压缩去维护并查集,因为这样会破坏原来的并查集结构。but我们可以用启发式并查集任然可以做到Ologn的复杂度。) 当删除一条边时,我们将父亲的标记下放给儿子(这里可能说的不准确,应该是父联通块的标记下传给即将分裂出去的儿子连通块),而加入一条边,为了避免重复加,我们需要减去之前父亲连通块的标记(不必担心会多减,因为最终所有的点都会分裂出去),在所有边都分裂完之后,就能保证原来的整个连通块都打上标记。

线段树分治的重点在于叶子结点,当 DFS 到叶子结点时,就是到了某个具体的时间点,我们可以对在这个时间点下的答案进行计算或者维护。

Problem - F - Codeforces

板子题

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>#define FOR() int le=e[u].size();for(int i=0;i<le;i++)
#define QWQ cout<<"QwQ\n";
#define ll long long#include <vector>
#include <queue>
#include <map>#define ls now<<1
#define rs (now<<1|1)using namespace std;
const int N = 1001010;
const int M = 2e5;
const int qwq = 303030;
const int inf = 0x3f3f3f3f;inline int read() {int sum = 0, ff = 1;char c = getchar();while (c < '0' || c > '9') {if (c == '-') ff = -1;c = getchar();}while (c >= '0' && c <= '9') {sum = sum * 10 + c - '0';c = getchar();}return sum * ff;
}int n, m, L[N], R[N], fa[N], tag[N];
vector<pair<int, int> > e[N << 3];void insert(int p, int l, int r, int x, int y, int u, int v) {if (x <= l && r <= y) {e[p].emplace_back(u, v);return;}int mid = (l + r) >> 1;if (x <= mid) insert(p << 1, l, mid, x, y, u, v);if (y > mid) insert(p << 1 | 1, mid + 1, r, x, y, u, v);}int tot, deep[N];
struct node {int x, y, depy;
} st[N << 3];int find(int x) {return fa[x] == x ? x : find(fa[x]);
}void merge(int u, int v) {int fu = find(u), fv = find(v);if (fu == fv) return;if (deep[fu] > deep[fv])swap(fu, fv);st[++tot] = {fu, fv, deep[fv]};fa[fu] = fv;deep[fv] += (deep[fu] == deep[fv]);tag[fu] -= tag[fv];
}void roll_back(int sz) {while (tot && sz < tot) {const auto &[x, y, depy] = st[tot];fa[x] = x;deep[y] = depy;tag[x] += tag[y];tot--;}
}void dfs(int p, int l, int r) {int sz = tot;for (auto [u, v]: e[p]) {merge(u, v);}if (l == r) {tag[find(1)]++;} else {int mid = (l + r) >> 1;dfs(p << 1, l, mid);dfs(p << 1 | 1, mid + 1, r);}roll_back(sz);}int main() {int x, y;n = read();m = read();for (int i = 1; i <= n; i++) {L[i] = read(), R[i] = read();}for (int i = 1; i <= m; i++) {x = read();y = read();int le = max(L[x], L[y]);int re = min(R[x], R[y]);if (le <= re) insert(1, 1, M, le, re, x, y);}for (int i = 1; i <= n; i++) fa[i] = i;dfs(1, 1, M);for (int i = 1; i <= n; i++) if (tag[i]) printf("%d ", i);return 0;
}

 

传送

有一个 n 个节点 m 条边的无向图,对于一条边有四个参数 (a,b,l,r) ,表示这条边在 [l,r] 这些时间连接 (a,b) 。

有一个传送技能:如果在某时刻 u 和 v 在一个连通块里,可以从 u 传送到 v 。

小 A 初始在节点 1 ,所以 小 A 想知道他能在 [1,n] 中的哪些时间点能直接从 1 传送到节点 i ,请你帮帮他。

由于输出量可能过大,考虑简化输出,假设所有能从 1 到达 i 的时间点为 ti,1…ti,k ,定义 ansi=∑kj=1ti,j ,你只需要输出一个 ⊕ni=1ansi 即可,其中 ⊕ 表示异或和。

杭电oj咋回事,一样的代码交了好几遍,有时候T有时候能过,有没有人给看看

#include <algorithm>
#include <iostream>
#include <vector>
#define ls now<<1
#define rs (now<<1|1)
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;int n, m;
vector<pair<int, int> > t[N << 2];
struct CZ {int x, y, depy;
} st[N];
int fa[N], dep[N];
ll tag[N];
int cnt;inline int read() {int sum = 0, ff = 1; char c = getchar();while(c<'0' || c>'9') { if(c=='-') ff = -1; c = getchar(); }while(c>='0'&&c<='9') { sum = sum * 10 + c - '0'; c = getchar(); }return sum * ff;
}int find(int x) { return x == fa[x] ? x : find(fa[x]); }void insert(int now, int l, int r, int x, int y, int u,int v) {if (x <= l && r <= y) {t[now].emplace_back(u,v);return;}int mid = l + r >> 1;if (x <= mid) insert(ls, l, mid, x, y, u,v);if (y > mid) insert(rs, mid + 1, r, x, y, u,v);
}void merge(int x, int y) {int xx = find(x), yy = find(y);if (xx == yy) return;if (dep[xx] > dep[yy]) swap(xx, yy);st[++cnt] = {xx, yy, dep[yy]};fa[xx] = yy;if (dep[xx] == dep[yy]) dep[yy]++;tag[xx] -= tag[yy];
}void DFS(int now, int l, int r) {int sz = cnt;for(auto &[u,v] : t[now]){merge(u,v);}if (l == r) {tag[find(1)] += l;} else {int mid = l + r >> 1;DFS(ls, l, mid);DFS(rs, mid + 1, r);}while (cnt > sz && cnt >=0 ) {const auto &[x,y,deep] = st[cnt];fa[x] = x;tag[x] += tag[y];dep[y] = deep;cnt -- ;}
}int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);n = read(),m=read();for (int i = 1,x,y,le,re; i <= m; i++) {x=read();y=read();le=read();re=read();insert(1, 1, n, le, re, x, y);}for (int i = 1; i <= n; i++) fa[i] = i;DFS(1, 1, n);ll ans = 0;for (int i = 1; i <= n; i++) {ans ^= tag[i];}printf("%lld" ,ans);return 0;
}

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

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

相关文章

使用 hutool工具实现导入导出功能。

hutool工具网址 Hutool参考文档 pom依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.20</version></dependency><dependency><groupId>org.apache.poi</gro…

ASP.NET Core在启动过程中使用数据库实例的几种方式

ASP.NET Core项目启动过程中若要调用SqlSugarClient实例操作数据库数据&#xff08;假设操作函数如下&#xff09;&#xff0c;特此记录以下几种方式&#xff1a; public class PublicDataBuffer {public static List<EnvironmentRecord> DataBuffer new List<Envir…

【BUG】已解决:ModuleNotFoundError: No module named ‘sklearn‘

已解决&#xff1a;ModuleNotFoundError: No module named ‘sklearn‘ 目录 已解决&#xff1a;ModuleNotFoundError: No module named ‘sklearn‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是…

Kotlin 基础语法

文章目录 一. 函数 一. 函数 Java中方法的叫法更普遍一些&#xff0c;Kotlin中函数的叫法更普遍一些&#xff1b;二者为同一东西 1. 标准写法 fun largerNumber(num1: Int, num2: Int): Int {return max(num1, num2) }2. 重要语法糖 当一个函数中只有一行代码时&#xff0c;K…

视频点播项目

文章目录 视频点播技术栈与项目环境JsonCppMariaDBhttplib 工具类设计文件类Json类 数据管理模块视频信息管理&#xff08;数据表设计&#xff09;数据管理类设计 网络通信接口设计业务处理模块设计前端界面主页面播放页面 项目总结项目回顾项目结构关键技术点总结 视频点播 允…

亚马逊自发货erp,虚拟自动化发货功能以及1688订单采购

亚马逊自发货erp自动化功能&#xff0c;自动同步订单&#xff0c;1688订单同步。 大家好&#xff0c;今天分享一个非常实用并且节省时间的功能&#xff1a;自动化发货以及1688同步订单。 首先来看下自动化发货功能怎么操作。 →要在商品信息里面添加商品信息&#xff0c;上传…

ubuntu系统下安装配置 8.0.37的MySQL

ubuntu系统下安装配置MySQL 8.0.37-0ubuntu0.22.04.3服务 安装mysql sudo apt update sudo apt install mysql-server sudo systemctl status mysql进入mysql&#xff0c;创建特定用户&#xff0c;专门用于登录 sudo mysql; create user user_nameip_address identified by …

风灵月影修改器未检测到游戏怎么回事?解决方法分享

当风灵月影修改器未检测到游戏进程时&#xff0c;可能是由以下几个原因导致的&#xff1a; 1. 游戏未启动&#xff1a; 最直接的原因就是游戏本身没有被启动&#xff0c;或者游戏还未完全加载完成&#xff0c;处于启动过程中的某个阶段&#xff0c;此时修改器可能检测不到游戏…

【总结】逻辑运算在Z3中运用+CTF习题

国际赛IrisCTF在前几天举办&#xff0c;遇到了一道有意思的题目&#xff0c;特来总结。 题目 附件如下&#xff1a;&#x1f4ce;babyrevjohnson.tar 解题过程 关键main函数分析如下&#xff1a; int __fastcall main(int argc, const char **argv, const char**envp){int v4…

【优质精选】12节大模型系列教学课程-更新中001

欢迎踏上这一精彩纷呈的大模型知识之旅&#xff01;这一系列课程是为了帮助您全面、深入地理解和掌握大模型领域的核心知识与前沿技术而精心设计的。 从基础概论开始&#xff0c;为您搭建起扎实的知识框架&#xff0c;让您对大模型的来龙去脉有清晰的认知。深入剖析 RAG、SFT、…

关于adcoder和codeforce 如何安装翻译插件

首先在扩展当中下载插件篡改猴 其次&#xff0c;点击获取新的脚本 最后搜索 atcoder better 和 codeforce better 安装即可

【Spring Boot】网页五子棋项目实现,手把手带你全盘解析(长达两万3千字的干货,坐好了,要发车了......)

目录 网页五子棋项目一、项目核心流程二、 登录模块2.1 前端输入用户信息2.2 后端进行数据库查询用户信息 三、 游戏大厅模块3.1 前端通过Ajax请求用户数据&#xff0c;后端从Session中拿取并从数据库中查询后返回3.2 前后端建立WebSocket连接&#xff0c;并进行判断&#xff0…

如何处理 PostgreSQL 中死锁的情况?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 如何处理 PostgreSQL 中死锁的情况&#xff1f;一、认识死锁二、死锁的症状三、死锁的检测四、预防死锁…

【MySQL】:想学好数据库,不知道这些还想咋学

客户端—服务器 客户端是一个“客户端—服务器”结构的程序 C&#xff08;client&#xff09;—S&#xff08;server&#xff09; 客户端和服务器是两个独立的程序&#xff0c;这两个程序之间通过“网络”进行通信&#xff08;相当于是两种角色&#xff09; 客户端 主动发起网…

Java语言程序设计——篇六(1)

字符串 概述创建String类对象     字符串基本操作实战演练 字符串查找字符串转换为数组字符串比较实战演练 字符串的拆分与组合 概述 字符串 用一对双引号“”括起来的字符序列。Java语言中&#xff0c;字符串常量或变量均用类实现。 字符串有两大类&#xff1a; 1&…

设计模式学习[2]---策略模式+简单工厂回顾

文章目录 前言1.简单工厂模式回顾2.策略模式3.策略模式简单工厂的结合总结 前言 上一篇讲到简单工厂模式。 在我的理解中工厂的存在就是&#xff0c;为了实例化对象。根据不同条件实例化不同的对象的作用。 这篇博客写的策略模式&#xff0c;可以说是把这个根据不同情况实例化…

pyinstaller 打包基于PyQt5和PaddleOCR的项目为.exe

简介&#xff1a; 最近做了一个小项目&#xff0c;是基于PyQt5和PaddleOCR的。需要将其打包为.exe&#xff0c;然后打包过程中遇到了很多问题&#xff0c;也看了很多教程&#xff0c;方法千奇百怪的&#xff0c;最后也是一步一步给试出来了。记录一下&#xff0c;防止以后忘记…

华为路由器SSH登录实验

概念 SSH全称安全外壳&#xff08;Secure Shell&#xff09;协议&#xff0c;这个协议的目的就是为了取代缺乏机密性保障的远程管理协议&#xff0c;SSH基于TCP协议的加密通道&#xff0c;让客户端使用服务器的RSA公钥来验证SSHv2服务器的身份。 创建密钥对 在充当SSH服务器的…

C语言随机数的生成相关案例

随机数的方式&#xff1a; 1、设置种子&#xff1a;srand(初始值) 2、获取随机数&#xff1a;rand(); 引导案例&#xff1a; 通过for循环简单生成10个随机数 #include<stdio.h> #include<stdlib.h> //添加包含随机数的库函数 int main() {srand(1); …

阿里巴巴Java开发手册学习笔记

1. 注释规范 类、属性、方法注释&#xff1a;必须使用Javadoc规范&#xff0c;格式为/*内容/&#xff0c;避免使用//。抽象方法注释&#xff1a;除了参数、返回值、异常外&#xff0c;还需说明功能。类创建信息&#xff1a;必须添加创建者和创建日期&#xff0c;格式为date yy…