当前位置: 首页 > 网络知识

[POJ1741]Tree(点分治模板)

时间:2026-01-29 09:38:43

传送门

良心解析

其实以前在求某段序列上的区间统计问题时就碰到过类似于这样的思想。

当时的区间统计问题思路大致是这样:

选取一个点作为中间点,从这个点的左边和右边统计出满足条件的点对。然后当前的中间点就可以删去了,接着递归统计左右两个区间的方案数。

其实这就是个分治和分类讨论的思想。

满足要求的解无非就是这两种:

1.区间包含中间点(也就是两端点在中间点的左右两边)

2.区间不包含中间点(也就是两个端点都在中间点的左边或右边)

所以正确性显而易见

淀粉质就是把这种思想应用于树上的路径统计上,选取一个点作为根,然后统计经过这个点的路径数,端点一定是在子树中的,

不过这会遇到一个问题,就是两个端点会在同一颗子树中,这就需要再统计子树中的答案再减去。接着再递归求解每一颗子树。

最后一个问题就是根节点的选取,需要选重心,防止出现链导致时间复杂度退化的情况。

其次是统计答案的方法,对于此题来说有个神奇的nlogn的方法,上面的链接中已经给出。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 100001#define INF ~(1 << 31)using namespace std;int n, K, cnt, root, tot, ans;int head[N], to[N], nex[N], val[N], f[N], size[N], deep[N], d[N];bool vis[N];//f[i]表示节点i的最大子树的大小//deep[i]表示节点i到根的距离 //vis[i] == 1 表示该节点删除 inline int read()inline void add(int x, int y, int z)//获取当前块的重心 inline void getroot(int u, int fa)f[u] = max(f[u], tot  size[u]);if(f[u] < f[root]) root = u;}//获取当前块中所有的点到根的距离 inline void getdeep(int u, int fa)}//求解经过当前根的满足条件的路径的方案数 inline int cal(int u, int now)//递归求解每一块 inline void work(int u)}int main()tot = n;f[0] = INF;getroot(1, 0);work(root);printf("%d\n", ans);}return 0;}

  



上一篇:[luoguP2495] [SDOI2011]消耗战(DP + 虚树)
下一篇:[BZOJ3611] [Heoi2014]大工程(DP + 虚树)
模板 点分治
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素