Day47【最小生成树】

ops/2024/10/9 2:46:43/

题目链接们

首先不难发现答案一定是某条边的权值,且该边两个端点的颜色不同。

类似于 CSP2022S-星战 的思路,我们把 m m m 条边先排序,再分为 m \sqrt m m 个块,并定义边 i i i 的 Hash 权值为 ( c o l u − c o l v ) × w i (col_u - col_v) \times w_i (colucolv)×wi,如果一个块内所有边的权值累和为 0 0 0,那么当前块内没有我们想要的边,否则如果有,暴力遍历当前块即可。

至于维护动态维护块 Hash 的值,先预先记录一下当前点的出边权值和与入边权值和即可,有手就行。
时间复杂度: O ( q × m ) O(q \times \sqrt m) O(q×m )

最小公倍树

不难发现复杂度瓶颈在于边数太多,所以考虑缩减边的规模。

考虑一个点序列 { a , b , c , d , . . . . , e , f , g } \{a,b,c,d,....,e,f,g\} {a,b,c,d,....,e,f,g},不失一般性地钦定 a < b < c < d < e < f < g a<b<c<d<e<f<g a<b<c<d<e<f<g,如果该序列两两 gcd ⁡ \gcd gcd 相等,那么只需要连边 ( a , b ) (a,b) (a,b) ( b , c ) (b,c) (b,c),… , ( f , g ) (f,g) (f,g) 即可,这就把边的规模缩减为 O ( n ln ⁡ n ) O(n\ln n) O(nlnn)

剩下的暴力 kruscal 即可。

Power Tree

好题,好题。

首先一眼看出树形结构没有用,求出每个点支配的叶子区间 [ l i , r i ] [l_i,r_i] [li,ri] 即可弃用树型结构。

不妨令叶子节点权值的差分数组为 e e e,那么 Alice 的操作实际上是: e l i ← e l i + v e_{l_i} \leftarrow e_{l_i}+v elieli+v e r i + 1 ← e r i + 1 − v e_{r_i+1} \leftarrow e_{r_i+1}-v eri+1eri+1v

接下来就是最小生成树的典中典结论,考虑把操作 ( l i , r i + 1 ) (l_i,r_i+1) (li,ri+1) 视为一条边,那么若两个点 u , v u,v u,v 联通,就意味着我们可以通过若干操作,达到直接操作 ( u , v ) (u,v) (u,v) 的效果。

那么题目条件等价于选择一些边 ( l i , r i + 1 ) (l_i,r_i+1) (li,ri+1),使得差分数组 e e e n + 1 n+1 n+1 个点联通,跑 kruscal 即可。
然而这道题要求所有方案的并集,所以权值相等的边要一起考虑,这一点很重要。

City 城市建设

好题,好题。

最近一个月已经见过三次这道题了。还有一次 noip 模拟赛考到这道题,赚麻了。

我们考虑线段树分治处理询问,假设当前处理到询问 [ l , r ] [l,r] [l,r]。现有如下两个 t r i c k trick trick

  • 我们把询问 [ l , r ] [l,r] [l,r] 中涉及到的边的边权强制置为 i n f inf inf,跑一遍 kruscal,那么不在当前最小生成树上的边,一定不会在其子区间的最小生成树上出现,我们直接把这些边删去即可。
  • 再考虑把 [ l , r ] [l,r] [l,r] 中涉及的边的边权强制置为 − i n f -inf inf,再跑一遍 kruscal,如果此时出现在最小生成树上的边权不为 − i n f -inf inf 的边,一定会出现在其子区间的最小生成树上,我们直接把这些边 U n i o n S e t UnionSet UnionSet 并累加这些边的贡献即可。

如果说人话就是,此题线段树分治的实质是时间分治,每个线段树节点都对应了一个最小生成树,如果把接下来可能边权会变的边置为极大值,那么就是在最好情况下, E − e ∈ [ l i , r i ] E - e\in [l_i,r_i] Ee[li,ri] 这些边的出现情况, 如果还不出现,那么就意味着,接下来无论怎么修改,这些边肯定不会出现,置为极小值也同理对应着最坏情况,如果这些边还出现了,那么无论接下来怎么修改 e ∈ [ l i , r i ] e \in [l_i,r_i] e[li,ri] 这些边的边权,它们都会出现。

不难发现第二种操作把点的规模缩减为了 O ( r − l ) O(r-l) O(rl),而第一种操作把边的规模缩减为了 O ( r − l ) O(r-l) O(rl),这样每个区间暴力跑 kruscal 的时间复杂度是对的。

具体实现上,对于每个线段树节点 p p p 求出其对应的询问区间 [ l p , r p ] [l_p,r_p] [lp,rp] 涉及到的边集 E q E_q Eq,然后每次递归时,维护一个当前边集 E E E,每次处理时,暴力把 E q E_q Eq 中的边置为极端值,然后用 E E E 中的边跑 kruscal,得到新的边集 E n x t E_{nxt} Enxt,然后下放 E n x t E_{nxt} Enxt,递归左右区间即可。

递归到叶子节点时修改边权,计算答案,线段树分治回撤时,用可撤销并查集即可。

时间复杂度: O ( q log ⁡ n log ⁡ q ) O(q \log n \log q) O(qlognlogq)

新年的繁荣

一眼 Brovaka 板子题,把板子复制下来改到一半发现 Trie 树处理不了形如 a i & a j a_i \& a_j ai&aj 这种形式的式子???

事实证明可以,如果当前位为 1 1 1,往 1 1 1 方向递归即可,如果当前位为 0 0 0,先预先把 1 1 1 方向的节点复制一遍丢到 0 0 0 方向里,然后递归 0 0 0 方向即可,好像时间复杂度是对的,但我不太会这种做法。

考虑针对于这道题的做法,注意到边权范围只有 [ 0 , 2 20 ) [0 , 2^{20}) [0,220),那么我们完全可以枚举边权。

首先把相同的数先合在一起,这显然是最优秀的,那么剩下来若干个互不相同的元素,我们枚举从大到小枚举边权 i i i,然后枚举满足 a x & a y = i a_x \& a_y = i ax&ay=i 的二元组 ( x , y ) (x,y) (x,y),然而这样复杂度是 O ( n 3 ) O(n^3) O(n3) 的,无法接受。

接下来考虑抽象的做法,假如说当前枚举到边权 i i i,那么满足 p o p c o u n t ( a x ) = p o p c o u n t ( i ) + 1 popcount(a_x) = popcount(i)+1 popcount(ax)=popcount(i)+1 a x a_x ax,实质上可以直接视为 i i i,那么我们转而枚举满足这样性质的 ( x , y ) (x,y) (x,y),如果 a a a 中原来没有 i i i,那么随便找一个 a x a_x ax 变成 i i i 即可,然后把这些 x , y x,y x,y 全部 U n i o n S e t UnionSet UnionSet 就完事了。

简要说一下正确性,因为我们从大到小枚举边权,所以要尽可能多的连这样的边,类似于或者说就是 Brovaka,而 a x a_x ax 直接变为 i i i 这种看似错误的操作,实际上是合法的,因为任意 a a a 中的元素被视为其二进制意义下的某个子集,不会使答案更优的。

免费道路

先自然想到一个假思路,把边顺序 random_shuffle 若干次然后跑生成树,发现已经有 k k k 条黑边了就停止加入黑边即可。

没试过,但正确率应该感人,为什么,因为图可能不连通,又是为什么,考虑一个问题:有些黑边是必须加的,换个意思说,不加这些黑边图联通不了!!!

所以我们先跑一边生成树,把白边先全加进去,再把黑边加进去,此时加入的黑边就是必须加的,然而这样有一个思维小漏洞,必须加入的黑边组成的集合不是唯一的,但我们任选其中一个集合是对的,为什么?因为无论选其中哪个集合,都能在最坏情况下保证图联通,满足了我们的最初目的。

接下来再跑一遍生成树,把这些黑边先加进去,再优先把剩余黑边往里面加,再加白边,最后判断一下黑边数量是否达到 k k k 条即可。

Sorting a Grid

好题,好题。

注意到 C C C 变为 D D D 的操作,“每一行任意排列”,那么行内的相对顺序是不重要的,这启发我们把在 D D D 矩阵中同一行的元素染成同一颜色,那么我们只需保证 C C C 矩阵每一行的颜色相同,就可以保证 C → D C \rightarrow D CD

接下来考虑 B → C B \rightarrow C BC,“每一列任意排列”,显然,我们只需要保证 B B B 矩阵每一列中每一种颜色恰好出现一次,那么 B B B 一定可以变为 C C C

那么原问题等价于,现在有一个 A A A 矩阵,其中有 n n n 种颜色,每种颜色恰有 m m m 个,现在我们对每一行任意排列,使得 A A A 矩阵每一列中每一种颜色恰好出现一次。

二分图典中典 t r i c k trick trick。把每一行向其包含的颜色连边,然后我们对每一列跑 m m m 次完美匹配,根据 Holl 定理易证明每次都是完美匹配。对于一个大小为 n n n 的匹配,其具体含义就意味着第 i i i 行,当前列的颜色为 m a t c h [ i ] match[i] match[i],由此我们求出了 B B B 矩阵,由 B B B C C C 应该人人都会吧。

这里简单用 Holl 定理证明一下,假设当前已经处理完了 k k k 列,对于左部点的一个子集 S S S, 其有一个邻点集和 S v S_v Sv,且 S S S S v S_v Sv ( m − k ) × ∣ S ∣ (m-k) \times |S| (mk)×S 条边,并且 S v S_v Sv 中每个点的度数 最多 m − k m-k mk (最开始为 k k k,每次完美匹配减 1 1 1),所以一定有 ∣ S ∣ ≤ ∣ S v ∣ |S| \le |S_v| SSv,得证。

二分图匹配板子题,把不能同时放置马的格子连起来,跑一个最大独立集就好了。

然而这样时间复杂度是 O ( n 2 m 2 ) O(n^2m^2) O(n2m2),所以要么打网络流,要么随机交换存边顺序就好了。

次小生成树

又称倍增复健题。


http://www.ppmy.cn/ops/122944.html

相关文章

OJ在线评测系统 后端微服务架构 注册中心 Nacos入门到启动

注册中心 服务架构中的注册中心是一个关键组件&#xff0c;用于管理和协助微服务之间的通信。注册中心的主要职责是服务的注册和发现&#xff0c;确保各个微服务能够相互找到并进行调用。 主要功能&#xff1a; 服务注册&#xff1a;微服务在启动时&#xff0c;将自身信息&am…

Authentication Lab | Timing Attacks

关注这个靶场的其它相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;Timing Attacks 前情提要 由于软件系统对不同输入处理时间的差异&#xff0c;可能会导致系统存在侧信道攻击的隐患。比如&#xff0c;如果输入的是无效的用户名&#x…

Windows系统编程(三)线程并发

进程与线程 进程&#xff1a;直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说&#xff0c;进程仅仅是一个数据结构&#xff0c;并不会真实的执行代码 线程&#xff1a;通常被称作但并不真的是轻量级进程或实际工作中的进程&#xff0c;它会真实的执行代码。每…

JavaScript函数基础(通俗易懂篇)

10.函数 10.1 函数的基础知识 为什么会有函数&#xff1f; 在写代码的时候&#xff0c;有一些常用的代码需要书写很多次&#xff0c;如果直接复制粘贴的话&#xff0c;会造成大量的代码冗余&#xff1b; 函数可以封装一段重复的javascript代码&#xff0c;它只需要声明一次&a…

全网最简单的ElasticSearch入门指引

文章目录 Elasticsearch概述1. Elasticsearch 的架构主要组件 2. Elasticsearch 的工作原理索引操作搜索操作分布式特性 3. Elasticsearch 的特点4. Elasticsearch 的核心功能文档操作查询语言聚合分析 5. Elasticsearch 的配置与管理一、配置文件二、核心配置参数 6. 应用场景…

怎么ping网络ip地址通不通

怎么Ping网络IP地址通不通&#xff1f;要检查网络中的IP地址是否连通&#xff0c;可以使用‌Ping命令。Ping命令通过发送ICMP&#xff08;Internet Control Message Protocol&#xff0c;因特网控制消息协议&#xff09;Echo请求报文并等待回应&#xff0c;来判断目标主机是否可…

MQTT协议简介

MQTT协议介绍 MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它具有轻巧、开放、简单、规范、易于实现的特点&#xff0c;适用于受限环境如机器与机器的通信&#xff08;M2M&#xff09;以及物联网环境&#xff08;IoT&#xff09;。以下是对MQTT协议的详细介绍&…

kafka-windows集群部署

kafka-windows集群部署目录 文章目录 kafka-windows集群部署目录前言一、复制出来四个kafka文件夹二、修改集群每个kafka的配置文件四、启动zookeeper&#xff0c;kafka集群 前言 部署本文步骤可以先阅读这一篇博客&#xff0c;这篇是关于单机kafka部署测试的。本文用到的文件…