P4178 Tree (点分治)
题目链接
一:我们考虑树上两点之间的路径有什么情况
1:经过根节点(即在根节点的两端)
2:不经过根节点(完全在一颗子树的一侧)
二:我们考虑这两种路径是否可以归为一类
1:对于第一种的情况两点间路径长度dis( u , v ) 可以看为dis ( u , root ) + dis ( root , v )
2:而对于第二种情况我们可以找到u , v 路径所在的子树,将根节点变为子树的根节点,然后就变为了第一种情况
3:总之,所以我们可以不断的递归根节点将所有情况转化为第一种情况
设b[ u ] 表示u属于哪一棵子树(b数组在算法进阶指南里说了,但是代码好像没有体现,而是用了容斥原理)
那么b[ u ] = b[ v ] ,d[ u ] + d[ v ] ≤ k满足条件的第一类路径条数即为满足条件的点对数
三:下面我们来讨论如何计算满足条件的点对数:
1:将目前子树中的节点到根节点的权值放入数组len中,并排序
用两个指针 L,R 扫描数组,每找到一个合法的答案就加上R −L ,就让L++,否则让 R --
2:发现问题
在指针扫描的过程中我们会出现不合的情况
根据len的定义我们存放的一颗树里面所有的边,这是我们计算calc计算时,可能会加上两条边在子树的同一侧的情况,我们可以发现不合法的路径在当前根的一颗子树上,即没有跨越两棵子树(如果跨越了它就合法了),所以们可以在遍历的时候减去不合法的情况(容斥)
3:具体的方法
ans+ = calc( u , 0 )
ans − =calc ( v , dis ( u , v ) )
这样即可做到不重不漏
四:总结
点分治步骤
- 找到树的重心
- 将重心视为根节点,那么树上任意两点有两种情况
- 路径经过根节点
- 路径不经过根节点
- 通过 calc 函数计算出第一种情况下的答案,把根节点从树中删去
- 对每棵子树递归执行上面的操作
calc函数的计算方法
- 计算出每个结点到根节点的距离 d [ i ]
- 将树上的结点按照 d [ i ] 递增排序
- 指针 l 指向 d [ 1 ] ,指针 r 指向 d [ n ]。
- 若 l 与 r 指向结点的距离小于 k ,则 ans + = r − l + 1 , l + + 。
- 否则 r − −。
- 当 l > = r 的时候退出循环。
- 按照上面的方法,会把不经过根节点的路径也算入进去。利用容斥原理修正答案:
五:更具体的做法,见注释
#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 18446, P = 13331;
const double eps = 1e-8;
int n, k, root, sum, ans;
vector<PII> g[N];
int siz[N], max_part[N], d[N], b[N], len[N];
bool st[N];
void get_root(int u, int fa) // 找出重心
{siz[u] = 1, max_part[u] = 0; // siz[i]为其子树的大小,max_part[i]为去掉i后的最大连通块大小for (auto ed : g[u]){int v = ed.xx;if (v == fa || st[v])continue;get_root(v, u);siz[u] += siz[v];max_part[u] = max(max_part[u], siz[v]);}max_part[u] = max(max_part[u], sum - siz[u]);if (max_part[u] < max_part[root]) // 一开始root为0,且将其赋值为 n即为maxroot = u;
}
void get_dis(int u, int fa) // 找出这颗子树的距离。
{len[++len[0]] = d[u]; // len[0]存放的是子树节点个数,len[i] 表示子树中的路径长度for (auto ed : g[u]){int v = ed.xx, w = ed.yy;if (v == fa || st[v])continue;d[v] = d[u] + w; // d[i] 表示i到根节点的距离,由上而下的去跟新d数组,因为子节点距离有父节点跟新而来,故在计算距离时只更新父节点即可get_dis(v, u);}
}
int calc(int u, int w) // 计算以u为根的第一种情况的答案,也就是在树的两边的,但是对于只在一边得还未计算
{d[u] = w, len[0] = 0; // 先给根节点一个值,如果为0说明在递归子树,不是0那就是再利用容斥出去冗余,将该子树的边数先归零get_dis(u, 0); // 计算改子树的距离根节点的距离sort(len + 1, len + len[0] + 1); // 将距离从小到大排序int res = 0;for (int l = 1, r = len[0]; l < r;) // 直到不论左移还是右移都大于k,if和else if 都进不去{if (len[l] + len[r] <= k) // l与最大的相加都小于k,其余也小于k{res += r - l; // 故加上r-l++l; // 右移左端点}elser--; // 否则左移右端点}return res; // 返回以u为根的所有情况的答案
}
void solve(int u)
{st[u] = 1; // 标记删除的重心,防止重复计算ans += calc(u, 0); // 加上以我为跟答案for (auto ed : g[u]) // 遍历子树{int v = ed.xx, w = ed.yy;if (st[v])continue;ans -= calc(v, w); // 减去不合法得情况,不合法的情况全都发生在一课子树上,这里为什么传w,因为我们要加上u与v的边权sum = siz[v]; // 不要忘记在以v为根节点时,要修改all_node 的大小root = 0;get_root(v, u); // 递归根节点,但是肯定会有重复solve(root); // 递归解决}
}
signed main()
{Ysanqian;cin >> n;sum = n;max_part[0] = n; // 让max_part[0]为n当一个哨兵,以便跟新max_part[i]for (int i = 1; i < n; i++){int a, b, c;cin >> a >> b >> c;g[a].pb({b, c}); // 建边g[b].pb({a, c});}cin >> k;get_root(1, -1); // 先找重心solve(root); //cout << ans << endl;return 0;
}
相关文章:
P4178 Tree (点分治)
题目链接 一:我们考虑树上两点之间的路径有什么情况 1:经过根节点(即在根节点的两端) 2:不经过根节点(完全在一颗子树的一侧) 二:我们考虑这两种路径是否可以归为一类 1࿱…...
Kubernetes 二进制搭建
Kubernetes 二进制搭建 一、二进制搭建 Kubernetes v1.201.1 部署准备1.2 操作系统初始化配置1.3 部署 etcd 集群1.3.1 etcd 作为服务发现系统,有以下的特点1.3.2 准备签发证书环境1.3.3 在 master01 节点上操作1.3.4 生成证书 1.4 部署 docker引擎1.4.1 部署 Maste…...

QT QtXlsx安装使用
QtXlsx介绍 QtXlsx是一个可以读取和写入Excel文件的库。它不需要Microsoft Excel,可以在Qt5支持的任何平台上使用。 这里一定是需要QT5支持的。 须知安装QtXlsx时,需要下载perl 1.安装perl 这里选择官网下载安装即可。 官网地址:https://p…...

Java医院信息化HIS管理系统源码
HIS模板分为两种:病历模板和报表模板。模板管理是运营管理的核心组成部分,是基层卫生健康云中各医疗机构定制电子病历和报表的地方,各医疗机构可根据自身特点特色定制电子病历和报表,制作的电子病历及报表可直接在业务系统中使用。…...

【Uni-App】uview 开发多端应用,密码显示隐藏功能不生效问题
出现的问题: 使用uview组件u-input框密码绑定时会出现右侧密码显隐图标不显示的问题 思路: 1.看了下uview源码,发现这有一段注释,我们需要把源码修改一下,问题出在这里 这行代码修改为 :password"password || …...
人工智能算法-SVM, KNN
目录 SVM, KNN区别 一、KNN算法概述 算法的描述: 二、关于K的取值 K的取法: 三、关于距离的选取 Euclidean Distance 定义: 四、总结 SVM, KNN区别...

计算机网络—TCP
这里写目录标题 TCP头格式有哪些为什么需要TCP,TCP工作在哪什么是TCP什么是TCP连接如何确定一个TCP连接TCP和UDP的区别,以及场景TCP和UDP能共用一个端口?TCP的建立TCP三次握手过程为什么是三次握手、不是两次、四次why每次建立连接࿰…...

Oracle到DM实时数据同步实施方案
目录 1 项目概述 2 需求分析 3 实施操作 3.1 历史数据全量同步 3.2 增量数据实时同步 4 问题总结 4.1 字符型非空约束 4.2 字符型唯一索引尾部空格 1 项目概述 将Oracle 11g RAC生产环境数据同步到DM8分析环境,Oracle数据库大小1.5T,日增归档10…...

WebRTC | 音视频实时通信的本质
目录 一、音视频实时通信的两种指标 1. 实时通信延迟指标 2. 视频相关的基本概念 3. 音视频服务质量指标 二、解决实时通信的主要矛盾 1. 增加带宽 A. 提供更优质的接入服务 B. 保证云端网络的带宽和质量 C. 更合理的路由调度策略 2. 减少数据量 A. 采用更好的压缩算…...

ApiPost的使用
1. 设计接口 请求参数的介绍 Query:相当于get请求,写的参数在地址栏中可以看到 Body: 相当于 post请求,请求参数不在地址栏中显示。 请求表单类型,用form-data json文件类型,用row 2. 预期响应期望 设置完每一项点一下生成响应…...

6、CCS 配置工程头文件批量添加路径的方法
1、进入到图示的框框里 2、编辑好需要添加的路径,并按ctrl c 3、选中include paths(-I)框框里的最后一条路径 4、然后ctrl v,这样路径就复制到预定义路径里了...

Visual Studio配置PCL库
Visual Studio配置PCL库 Debug和Release配置新建项目配置属性表测试参考 Debug和Release Debug和Release的配置过程一模一样,唯一区别就在于最后一步插入的附加依赖项不同,因此下面以debug为例。 配置新建项目 1、新建一个C空项目,模式设置…...

数据分析 | 为什么Bagging算法的效果优于单个评估器
1. 回归问题如何降低方差 以随机森林为例,假设随机森林中含有n个弱评估器,由于子样本集的相似性以及使用的是同种模型,因此各模型有近似相等的方差和偏差,因此假设任意弱评估器上输出结果为,方差均为,则随机森林的输出…...

mysql架构介绍
1.整体架构图 我们发现整体的体系是由连接层、服务层、引擎层和物理文件存储层组成。 1.连接层 连接层是处理客户端和服务端之间的通信的,比如一些连接处理、授权验证等等。 2.服务层 服务层主要完成核心的功能,如SQL接口,就是用来接收…...

EIK+Filebeat+Kafka
目录 一、Kafka 概述 1)为什么需要消息队列(MQ) 2)使用消息队列的好处 (1)解耦 (2)可恢复性 (3)缓冲 (4)灵活性 & 峰值处理…...

python安装xgboost报错
ERROR: Could not find a version that satisfies the requirement xgboost (from versions: none) ERROR: No matching distribution found for xgboost 解决办法: 换成国内的pip源 pip install xgboost -i http://pypi.doubanio.com/simple/ --trusted-host py …...

语音芯片的型号有哪些?为什么强烈推荐使用flash型可擦写的
一、语音芯片的简介 语音芯片的型号有哪些?为什么强烈推荐使用flash型可擦写的芯片。这里我们简单描述一下如下常见类容: 1、他们都有什么特点?以及发展的历程简介 2、常见的语音芯片有哪些? 3、为什么推荐使用flash型可以重复…...

【OpenCV常用函数:轮廓检测+外接矩形检测】cv2.findContours()+cv2.boundingRect()
文章目录 1、cv2.findContours()2、cv2.boundingRect() 1、cv2.findContours() 对具有黑色背景的二值图像寻找白色区域的轮廓,因此一般都会先经过cvtColor()灰度化和threshold()二值化后的图像作为输入。 cv2.findContous(image, mode, method[, contours[, hiera…...
opencv,opengl,osg,vulkan,webgL,opencL,cuda
OpenCV OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C 类构成,同时提供了Python、Ruby、MATLAB等…...

golang拥有wireshark数据包解析能力
golang拥有wireshark数据包解析能力 1. 功能和实现 wireshark拥有世界上最全面的协议解析能力并且还在不断更新中,通过调研,没有办法找到与wireshark同水平的解析工具。 为了使得golang语言可以拥有wireshark一样强大的协议解析能力,库 gowir…...

thinkphp-queue队列随笔
安装 # 创建项目 composer create-project topthink/think 5.0.*# 安装队列扩展 composer require topthink/think-queue 配置 // application/extra/queue.php<?php return [connector > Redis, // Redis 驱动expire > 0, // 任务的过期时间…...
STM32实战:数字音频播放器开发指南
基于STM32的数字音频播放器/效果器是个很棒的项目!这涉及到多个嵌入式开发的关键技术点。下面我为你拆解实现方案和关键学习内容: 系统架构概览 [SD Card] -> [File System (FATFS)] -> [Audio Decoder (WAV/MP3)] -> [DSP Processing (EQ, R…...
使用API网关Kong配置反向代理和负载均衡
简介 Kong 是一个微服务API网关。 Kong是一个云原生,快速,可扩展和分布式微服务抽象层(也称为API网关,API中间件或在某些情况下为Service Mesh)。 作为2015年的开源项目,其核心价值在于高性能和可扩展性。…...

2025服装收银系统推荐:智能管理助力服装商家高效经营
在服装批发零售行业,一套高效的收银系统不仅能简化日常经营流程,还能通过数据分析帮助商家优化库存、提升销售。随着AI技术的普及,现代收银系统已不再局限于简单的记账功能,而是能提供智能选品、库存预警、精准营销等进阶服务。 …...
解决 VSCode 中无法识别 Node.js 的问题
当 VSCode 无法识别 Node.js 时,通常会出现以下症状: 代码提示缺失require 等 Node.js API 被标记为错误调试功能无法正常工作终端无法运行 Node.js 命令 常见原因及解决方案 1. Node.js 未安装或未正确配置 解决方法: 确保已安…...

1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
1panel面板中部署SpringBoot和Vue前后端分离系统 一,1panel面板部署二,安装OpenResty三,安装MySQL,Redis等Spring boot 运行依赖环境四,SpringBoot 应用配置及打包部署配置打包部署 五 ,前端VUE应用配置打包…...

JavaScript性能优化实战:从核心原理到工程实践的全流程解析
下面我给出一个较为系统和深入的解析,帮助你理解和实践“JavaScript 性能优化实战:从核心原理到工程实践的全流程解析”。下面的内容不仅解释了底层原理,也结合实际工程中的最佳模式和工具,帮助你在项目中贯彻性能优化理念&#x…...

Web前端之原生表格动态复杂合并行、Vue
MENU 效果公共数据纯原生StyleJavaScript vue原生table 效果 原生的JavaScript原生table null 公共数据 const list [{id: "a1",title: "第一列",list: [{id: "a11",parentId: "a1",title: "第二列",list: [{ id: "…...
游戏设计模式 - 子类沙箱
核心思想 子类沙箱模式(Subclass Sandbox)通过将核心逻辑封装在基类中,为子类提供安全的"沙箱"环境。子类通过组合或重写基类提供的预定义操作来实现行为,而非直接操作底层系统。 这种模式在游戏开发中常用于实现角色…...
ubuntu 端口复用
需求描述:复用服务器的 80端口,同时处理 ssh 和 http 请求,也就是 ssh 连接和 http 访问服务器的时候都可以指定 80 端口,然后服务器可以正确分发请求给 ssh 或者 http。 此时,ssh 监听的端口为 22,而 htt…...