点分治中重点需要注意:
- 统计ans的时候,一定要注意子树中的ans和当前根节点的ans的处理关系
- 切记要注意重心的处理
一、P3806 【模板】点分治1
思路:
- 将一颗子树的点到根的距离存入到一个栈中,这个栈维护当前重心的所有子树的距离信息
- 我们在得子树点到根信息后,我们在枚举进行距离的判断,我们判断完再进行信息的入栈。
code:
/*
* @Author: 0iq_love_zy
* @LastEditTime: 2021-02-21 18:35:44
* @优快云 blog: https://blog.youkuaiyun.com/acm_durante
* @E-mail: 1055323152@qq.com
* @ProbTitle:
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
#define lson p << 1 , l, mid
#define rson p << 1 | 1, mid + 1, r
#define mem(a, b) memset(a, b, sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const double PI = acos(-1.0);
const int N = 2e4+5,M = 1e7+5;
int n,m,ask[105],cnt,head[N];
struct node{
int v,w,net;
}e[N];
void add(int u,int v,int w){
e[++cnt].v = v;
e[cnt].w = w;
e[cnt].net = head[u];
head[u] = cnt;
}
int sz[N],sum,mx[N],root;
bool vis[N];
void get_root(int u,int fa){
sz[u] = 1;
mx[u] = 0;
for(int i = head[u]; ~i ; i = e[i].net){
int v = e[i].v;
if(vis[v] || v == fa) continue;
get_root(v,u);
sz[u] += sz[v];
mx[u] = max(mx[u],sz[v]);
}
mx[u] = max(mx[u],sum - mx[u]);
if(mx[u] < mx[root]){
root = u;
}
}
int dis[N],dd[N],tot;
void get_dis(int u,int fa){
dd[++tot] = dis[u];
for(int i = head[u]; ~i ; i = e[i].net){
int v = e[i].v, w = e[i].w;
if(v == fa || vis[v]) continue;
dis[v] = dis[u] + w;
get_dis(v,u);
}
}
queue<int>que;
bool tf[M],ans[M];
void dfz(int u,int fa){
tf[0] = 1;
que.push(0);
vis[u] = 1;
for(int i = head[u]; ~i ; i = e[i].net){
//case1:经过u
int v = e[i].v;
if(v == fa || vis[v]) continue;
dis[v] = e[i].w;
tot = 0;
get_dis(v,u);
rep(j,1,tot)
rep(z,1,m){
if(ask[z] >= dd[j]) ans[z] |= tf[ask[z] - dd[j]];
}
rep(j

本文介绍了点分治算法在解决树形结构问题中的应用,包括求解点对距离、小于特定距离的点对数量等。通过二分查找和递归处理,实现了高效的解决方案,并提供了详细的代码实现,涉及了树的重心、子树距离信息统计等关键步骤。
最低0.47元/天 解锁文章

465

被折叠的 条评论
为什么被折叠?



