洛谷 P3806 [模板] 点分治 1 题解

从三个角度理解知识图谱 2012年谷歌首次提出“知识图谱”这个词,由此知识图谱在工业界也出现得越来越多,对于知识图谱以及相关概念的理解确实也是比较绕。自己在研究大数据独角兽Palantir之后开始接触知识图谱,也算对其有了一定了解,这里从三个角度总结一下怎么去理解知识图谱。 几个基本概念:本体、实体、知识库、知识图谱 1、本体是概念的集合,是大家都公认的概念框架,一般不会改变如“人”、“事”、“物”、 “地”、“组... 阅读详情

【模板】点分治 1

题目描述

给定一棵有 nnn 个点的树,询问树上距离为 kkk 的点对是否存在。

输入格式

第一行两个数 n,mn,mn,m。

第 222 到第 nnn 行,每行三个整数 u,v,wu, v, wu,v,w,代表树上存在一条连接 uuu 和 vvv 边权为 www 的路径。

接下来 mmm 行,每行一个整数 kkk,代表一次询问。

输出格式

对于每次询问输出一行一个字符串代表答案,存在输出 AYE,否则输出 NAY。

样例 #1

样例输入 #1

2 1
1 2 2
2

样例输出 #1

AYE

数据规模与约定

  • 对于 30%30\%30% 的数据,保证 n≤100n\leq 100n≤100。
  • 对于 60%60\%60% 的数据,保证 n≤1000n\leq 1000n≤1000,m≤50m\leq 50m≤50 。
  • 对于 100%100\%100% 的数据,保证 1≤n≤1041 \leq n\leq 10^41≤n≤104,1≤m≤1001 \leq m\leq 1001≤m≤100,1≤k≤1071 \leq k \leq 10^71≤k≤107,1≤u,v≤n1 \leq u, v \leq n1≤u,v≤n,1≤w≤1041 \leq w \leq 10^41≤w≤104。

思路

树上的路径分为两类, 经过根节点root的路径和包含于root的某棵子树里(即不经过root)的路径。对于经过根节点的路径,节点u到节点v的路径长度即为u到根节点的路径长度加上v到根节点的路径长度。而对于不经过根节点的路径,可以找到所在子树的根,然后转化为求经过根节点的路径,也就是分治做法。但是需要注意的是,随便找一个根节点进行点分治的做法最坏时间复杂度会达到O(n2n^2n2),不能接受。因此可以先找到树的重心,以重心作为根节点进行点分治,这样复杂度可以降到O(nlognnlognnlogn)。此外,对于m次询问的处理,可以先将所有询问读入数组,然后在进行点分治的过程中处理所有询问,判断是否存在距离为k的点对。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e4 + 6;
const int maxm = 1e2 + 6;
const int maxk = 1e7 + 6;

int n, m;

struct edge
{
    int to; // 边的指向
    int w;  // 边权
};

vector<edge> e[maxn];

int _size[maxn];  // 以i为根的子树的结点数
int max_size;     // 求重心时的删除某结点后剩余子树结点个数的最大值的最小值
int sum;          // 当前子树的结点数
int root;         // 当前子树的根
int del[maxn];    // 处理过的子树的根标记为已删除
int dis[maxn];    // 以某个点为根时各个点到根节点的距离
bool judge[maxk]; // 到根节点的距离为i是否存在
int query[maxm];  // 记录询问
bool ans[maxm];   // 第i个询问是否可满足

void add_edge(int u, int v, int w) // 加边函数
{
    e[u].push_back({v, w});
}

void get_root(int u, int vis) // 找到重心,以重心为根
{
    int cur_max_num = 0;
    _size[u] = 1;
    for (int i = 0; i < e[u].size(); i++)
    {
        int v = e[u][i].to;
        if (v == vis || del[v])
            continue;
        get_root(v, u);
        _size[u] += _size[v];
        cur_max_num = max(cur_max_num, _size[v]);
    }
    cur_max_num = max(cur_max_num, sum - _size[u]);
    if (cur_max_num < max_size)
    {
        max_size = cur_max_num;
        root = u;
    }
}

void get_distance(int u, int vis, vector<int> &len) // 求子树中各个点到根节点的距离
{
    len.push_back(dis[u]);
    for (int i = 0; i < e[u].size(); i++)
    {
        int v = e[u][i].to;
        if (v == vis || del[v])
            continue;
        dis[v] = dis[u] + e[u][i].w;
        get_distance(v, u, len);
    }
}

void cal_path_length(int u) // 计算路径长度
{
    del[u] = 1;   // 记录以u为根的树已经计算过路径
    judge[0] = 1; // 预处理距离为0存在

    set<int> need_to_clear; // 记录需要清空的judge下标

    for (int i = 0; i < e[u].size(); i++)
    {
        int v = e[u][i].to;
        if (del[v])
            continue;
        // 离散化存储该子树中所有距离根结点的路径长度
        vector<int> len;
        // 求出子树v的各个结点到根u的距离
        dis[v] = e[u][i].w;
        get_distance(v, u, len);
        // 枚举距离和询问,将各个子树到根u的距离进行组合求和,判断是否存在该询问对应的距离之和
        for (int j = 0; j < len.size(); j++)
        {
            for (int k = 1; k <= m; k++)
            {
                if (query[k] >= len[j])
                {
                    if (judge[query[k] - len[j]] == 1)
                        ans[k] = 1;
                }
            }
        }
        // 记录先前子树到根的距离,用于后续子树与先前子树的组合求和
        for (int j = 0; j < len.size(); j++)
        {
            if (len[j] <= 1e7)
            {
                judge[len[j]] = 1;
                need_to_clear.insert(len[j]);
            }
        }
    }
    // 清空judge
    for (set<int>::iterator it = need_to_clear.begin(); it != need_to_clear.end(); it++)
    {
        judge[*it] = 0;
    }
}

void divide(int u) // 分治
{
    cal_path_length(u); // 计算经过根u的所有路径长度
    // 对u的子树分治
    for (int i = 0; i < e[u].size(); i++)
    {
        int v = e[u][i].to;
        if (del[v])
            continue;
        // 对子树进行分治,要更新sum和max_size为子树的大小
        sum = _size[v];
        max_size = _size[v];
        get_root(v, 0);
        divide(root);
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    int a, b, c; // 连接a和b的边权为c的路径
    for (int i = 1; i <= n - 1; i++)
    {
        cin >> a >> b >> c;
        add_edge(a, b, c);
        add_edge(b, a, c);
    }

    int k;
    for (int i = 1; i <= m; i++)
    {
        cin >> k;
        query[i] = k;
    }

    sum = n;
    max_size = n;
    get_root(1, 0);    // 寻找重心
    get_root(root, 0); // 通过该重心,更新所有子树的大小
    divide(root);

    for (int i = 1; i <= m; i++)
    {
        if (ans[i])
            cout << "AYE" << '\n';
        else
            cout << "NAY" << '\n';
    }

    return 0;
}
Unity中语法糖带来的GC问题 ——那些看起来优雅、实际上在背后偷偷生垃圾的代码 *语法糖(Syntactic Sugar)**指的是编程语言中为了让代码更简洁、易读而提供的简便写法。比如C#中的foreachlambda表达式LINQ自动属性等。语法糖本身不是坏事,但在Unity等对GC敏感的环境下,要警惕语法糖带来的隐式内存分配。合理使用语法糖,关键场合用更“丑陋”但高效的写法,才能保证游戏流畅运行。下面我将更深入地分析Unity中语法糖导致GC的原理、具体场景、检测与优化技巧,并补充一些容易忽视的细节。 阅读详情

相关推荐

Unreal5(虚幻五) 实现UI与C++代码逻辑的交互 保姆级教程

本人有Unity基础,刚学UE几天,把这一套处理流程记录一下备用。

qq_42915442的博客 9815

【洛谷】P3806

分治 #树形结构 #双指针。

Antonio915的博客 896

西门子 标准程序解读---> 机器手抓取和涂胶控制程序

摘要 该程序实现机械手在OP70/OP90工位的自动化控制,核心功能包括: 流程控制:分段(Seg1-Seg11)管理抓件、涂胶、放件等动作,结合DB1050/DB1250数据块监控工位状态及变位机位置反馈。 安全机制:配置干涉区(FC124)、实时检测安全光/急停信号,防止碰撞;服务程序(FB191)支持维修位触发与安全隔离。 参数配置:通过DB块关联机器人速度、节拍(FB27)、车型编码(如空过=2)及手自动模式(DB70.DBX21.2)。 应用场景:适用于汽车焊接/装配线

工控智联驿站 1239

洛谷P3806点分治题解

题目链接:https://www.luogu.org/problem/P3806 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在。 输入格式 n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行每行询问一个K 数据范围:对于100%的数据n<=10000,m<=100,c<=10000,K<=10000000 输出格式 对于每个K每行...

qq_41418281的博客 284

【Unity Animation 2D】从零到一:骨骼绑定与IK动画实战指南

本文详细介绍了Unity中2D骨骼绑定与IK动画的实战流程,从角色素材准备、骨骼系统创建到权重绘制和IK设置,逐步指导开发者掌握2D动画制作技巧。通过反向动力学(IK)技术,实现更自然的角色动画效果,适用于游戏开发和动画制作。

weixin_30430677的博客 370

CATIA V5新手必看:从零开始的界面导航与基础操作指南(附常见问题解决)

本文为CATIA V5新手提供全面的界面导航与基础操作指南,涵盖核心工作区解析、文件管理规范、视图操作秘籍及常见问题解决方案。通过详细的步骤说明和实用技巧,帮助用户快速掌握这一工业设计标杆软件,特别适合从SolidWorks、AutoCAD等软件过渡的用户。

b9c0d的博客 527

洛谷 P3806 (点分治)

题目:https://www.luogu.org/problem/P3806 题意:一棵树,下面有q个询问,问是否有距离为k的点对 思路:牵扯到树上路径的题都是一般都是点分治,我们可以算出所有的路径长度然后保留下来,点分治无非就是几步一直递归,点分治就是在树上递归 1,找树的重心 2,算出所有点到重心距离,找出当前重心的所有合法路径 3,递归到子树 然后反复执行这三步 其实...

weixin_30649641的博客 136

京东联盟h5st(3.1)加密参数逆向实战与反爬对抗策略

本文详细解析了京东联盟h5st(3.1)加密参数的逆向分析与实战破解过程。通过接口分析定位关键加密函数,拆解h5st结构并还原其基于SHA256和HMAC-SHA256的加密逻辑,最终使用Python集成JavaScript环境成功复现加密算法,并分享了应对反爬的频率限制、IP封禁及算法升级等对抗策略。

weixin_29246195的博客 1738

点分治学习笔记 / 洛谷 P3806【点分治】

由于树可以自由变换根节点,所以用重心来替换根节点,进行优化。由于某些原因,洛谷模板题需要提前预处理。:将经过当前的根节点的路径处理好。:找到当前子树的重心。:递归枚举儿子节点。...

willem248的博客 269

为R720安装iDRAC Service Module

这玩意找了好久资料, 教程都不咋靠谱, 要不就是有不理解的地方 所以直接一路莽着过河: 去官网找到设备对应的驱动程序: 几个查找筛选项看图 官网链接: https://www.dell.com/support/home/zh-cn/product-support/product/poweredge-r720/drivers 在下方的列表中找到对应系统版本的驱动并下载: 由于安装的系统为ESXi 6.5 U2 Dell定制版, 这里没有刚好的驱动, 所以下了个兼容的: 下载好后是一个压缩包:

Janus 6361

YOLOV8改进:添加Wiseiou,有效涨点

【代码】YOLOV8改进:添加Wiseiou,有效涨点。

AIcurator的博客 2391

洛谷-分治

凑字

MrJinNEU的博客 475

代码接单:用 ComfyUI 搭建电商模特换装工作流(保姆级教程)

在闲鱼和小红书上,搜一下“AI 模特图”或者“服装换模特”,你会发现大量的接单需求。太贵:请个外模拍一套图,动辄几千块。太慢:寄样品、排期、拍摄、修图,半个月过去了。太卷:竞对都在上新,你还在等图。“给我一张你的衣服平铺图(或假人图),我 10 分钟给你生成真人上身图,一张只要 50 块。对于商家是省钱,对于你是纯利润。为什么不用 Midjourney?因为 MJ 抽卡不可控,无法保持衣服版型一致。只有 ComfyUI,才能做到精准控制,实现工业化量产。

BUG猿的博客 1775

【洛谷P3806 【模板】点分治1】点分治

P3806 其实点分治去年学过 但是去年只学了个皮毛 所以这次又重新写一篇题解 尽可能写的详细 首先我们要清楚点分治的本质 在我看来 点分治通常是在树上操作 虽然名字叫做点分治 但是本质在我看来是树分治 你可以通过找到一个点 来把树划分层次 通过对不同子树的操作来统计答案 网上对于点分治的讲解还蛮多的 希望这次自己能理解通彻点分治 /* if you can't see the repay...

我是谁 --- 卡比兽 215

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

点分治学习笔记 & luogu P3806 【模板】点分治1

背景: 好久没看。忘记了。 题目传送门: https://www.luogu.org/problemnew/show/P3806 思路: 点分治模板。 留下一个模板。 代码: #include<cstdio> #include<cstring> #include<algorithm> #define INF 2147483647 using name...

zsyz_ZZY的博客 409

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

专题·点分治【including 点分治,洛谷P3806·【模板】点分治1及例题

初见安~几百年没写专题了来整理一波:) 点分治 1.概念 众所周知,分治是一种算法思想层面的东西【大雾。那么点分治是什么呢——通过静态的运算统计出树上一定条件下路径的一种算法。诸如在树上求路径长度<=K的路径数量之类的。 那么对于分治,这一思想上的体现在于——因为路径有直链和折链,假设我们要求的是路径长度不超过K的路径数量,并且在以1为我们统计的路径的LCA的状况下,我们是不是可以通...

樱狸✨愿携清风归来处 360

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

洛谷P3806 【模板】点分治1

题目背景 感谢hzwer的点分治互测。 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在。 输入输出格式 输入格式: n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行每行询问一个K 输出格式: 对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号) 输入输出样例 输入样例#1: 2 1 1 2 2 2...

FlyingJack 243

洛谷P3806 【模板】点分治1(点分治 模板题)

题目 给定一棵有n(n<=1e4)个点的树 询问树上距离为k(k<=1e7)的点对是否存在 询问m(m<=100)组 思路来源 https://www.cnblogs.com/bztMinamoto/p/9489473.html https://baijiahao.baidu.com/s?id=1608747083240620752&wfr=spider&am...

小衣同学的博客 479

洛谷 P3806 【模板】点分治1

This way 题意: 题解: 点分治模板 点分治解决的好像大部分是树上路径问题 网上模板有很多,我就不赘述了,大致思想就是找到树的重心,然后O(n)地求出路径经过这个点的所有情况,之后再将树以这个重心为基准分成多个子树,再找到他们的重心,如此分治的去做。网上的代码各不相同,我找了同集训队的人的写法,用set维护每个值是否出现,总的时间复杂度大概是O(nlog2n)O(nlog^2n)O(nlog2n)? #include<bits/stdc++.h> using namespace st

天翼之城的博客 233

P3806 【模板】点分治1(CDQ分治)

题目链接:https://www.luogu.org/problemnew/show/P3806 题目大意:中文题目 具体思路:直接dfs好像会超时,然后我们就开始想优化的方法,然后就是一个CDQ入门题了,我们可以分解成许多子问题进行解决,然后对于一棵树的话,我们最好的切入点就是这棵树的重心了,这样就能使得复杂度尽可能的低了,然后就不停的往下递归找每一棵子树的重心进行求解就可以了,然...

diaomeijiao3430的博客 178

洛谷 P4178 Tree 题解 点分治

点分治 深度优先搜索 树的重心 双指针 容斥 洛谷题解 C++代码 附详细注释

一只摸鱼的bbc 1315

P3806 【模板】点分治1

题面 https://www.luogu.org/problem/P3806 题解 #include<cstdio> #include<algorithm> #include<iostream> #include<vector> #define p rem[0] using namespace std; const i...

weixin_30362233的博客 73

点分治学习模板及一些例题

点分治 这里没有动态点分治。。 点分治是解决树上问题的一类算法,很多复杂度能从暴力的O(n2)O(n^2)O(n2)降低到O(nlogn)O(nlogn)O(nlogn). 具体做法是就是求一个树的重心,树的重心的性质,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。 就是说子树的大小可以lognlognlogn的降低,这样复杂度就降下来了。 如...

KXL5180的博客 396

P3806 【模板】点分治1(题解)(点分治)

P3806 【模板】点分治1(题解)(点分治) 洛谷题目传送门 #include&lt;iostream&gt; #include&lt;cstdlib&gt; #include&lt;cstdio&gt; #include&lt;cmath&gt; #include&lt;cstring&gt; #include&lt;iomanip&gt; #include&lt;algorithm...

eternal风度 210

洛谷P3806 【模板】点分治1 【点分治】

题意: 给出一棵树,每条边都有一个权值www,mmm次询问,每次询问树上是否有一条长度为kkk的路径 题解: 点分治模板题,但是处理起来麻烦 #include<iostream> #include<sstream> #include<string> #include<queue> #include<map> #include<unordered_map> #include<set> #include<vector&gt

qq_50554695的博客 137
上一篇: 洛谷 P1364 医院设置 题解 带权树的重心
下一篇: 洛谷 P4178 Tree 题解 点分治
bbc_ouo
博客等级 码龄3年 2096粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值