hihocoder1065 点分治 【 全图传送 】

题意:1e5的一棵树,有点权有边权。 1e5次操作,每次操作询问离点u边距不超过r的最大点权的点的编号是多少,如果多个最小输出最小编号的那个。

思路:开始想是不是树剖分啊,后来感觉不太靠谱,然后就搜了一发,也没发现有什么靠谱的解法。

后来看到昂神的的几句题解,怒敲一发点分治。开始以为不太好写,后来发现其实还好。

离线的做法(在线的没想到怎么写), 复杂度O((n+m)log^2 (n))。 对于一个分治点,搜索出有关的询问,这里每个把每条路径用分治重心拆成两半,像所有的点分治一样,这里会有一个同一颗子树的问题,然后这里并没有什么关系的,证明就是,假设两个点在一颗子树里,接下来的分治仍然会更新这对点,直到不在一颗子树为止,并且答案只会更精确。 对于每一次自问题处理就是分治内的点按照离分治重心的距离排序,再预处理出一个最大前缀数组,显然有单调性啊,所以可以对于每个询问就可以二分处理了。


#include <cstdio>
#include <vector>
#include <utility>
#include <cstring>
#include <iostream>
#include <algorithm>
const int maxn = 100007;
const int INF  = 1 << 30;
bool vis[maxn], isQ[maxn];
int size[maxn], head[maxn], maxe[maxn], ans[maxn], fin[maxn];
int val[maxn], pre[maxn], deep[maxn], E_cnt, n, m;

struct Node
{
	int w, id;
	Node() { }
	Node(int w, int id)
	:w(w), id(id) {   }
	bool operator < (const Node &x) const { return w < x.w; }
};

std::vector<Node> dis;
std::vector<std::pair<int, int> > ques[maxn];

struct Edge
{
	int v, w, next;
	Edge() { }
	Edge(int v, int w, int next):v(v), w(w), next(next) { }
}edges[maxn * 3];

void init()
{
	E_cnt = 0;
	memset(head, -1, sizeof(head));
	memset(vis,  0, sizeof(vis));
}

void addEdge(int u, int v, long long w)
{
	edges[E_cnt] = Edge(v, w, head[u]); head[u] = E_cnt ++;
	edges[E_cnt] = Edge(u, w, head[v]); head[v] = E_cnt ++;
}

void getSize(int u, int par)
{
	size[u] = 1;
	maxe[u] = 0;
	for(int i = head[u]; ~i; i = edges[i].next) {
		int v = edges[i].v;
		if(v == par || vis[v]) continue;
		getSize(v, u);
		size[u] += size[v];
		maxe[u] = std::max(maxe[u], size[v]);
	}
}

int min_node, root;
void getRoot(int u, int par, int r)
{
	maxe[u] = std::max(maxe[u], size[r] - size[u]);
	if(min_node > maxe[u]) {
		min_node = maxe[u], root = u;
	}
	for(int i = head[u]; ~i; i = edges[i].next) {
		int v = edges[i].v;
		if(v == par || vis[v]) continue;
		getRoot(v, u, r);
	}
}

void getDis(int u, int par, int dep, std::vector<int> & vec)
{
	deep[u] = dep;
	dis.push_back(Node(dep, u));
	if(isQ[u]) vec.push_back(u);
	for(int i = head[u]; ~i; i = edges[i].next) {
		int v = edges[i].v;
		if(v == par || vis[v]) continue;
		getDis(v, u, dep + edges[i].w, vec);
	}
}

void cal(int root)
{
	dis.clear();
	std::vector<int> vec;
	getDis(root, root, 0, vec);
	std::sort(dis.begin(), dis.end());
	int index = 0;
	for(int i = 0; i < dis.size(); i ++) {
		int now = dis[i].id;
		if(val[index] < val[now]) index = now;
		else if(val[index] == val[now] && now < index) index = now;
		pre[i] = index;
	}
	for(int i = 0; i < vec.size(); i ++) {
		int u = vec[i];
		for(int j = 0; j < ques[u].size(); j ++) {
			int w = ques[u][j].first - deep[u];
			int k = std::upper_bound(dis.begin(), dis.end(), Node(w, 0)) - dis.begin() - 1;
			if(k < 0) continue;
			int x = ques[u][j].second;
			int id = ans[x];
			if(val[id] < val[pre[k]]) ans[x] = pre[k];
			else if(val[id] == val[pre[k]] && id > pre[k]) ans[x] = pre[k];
		}
	}
}

void divid(int u)
{
	min_node = INF;
	getSize(u,  u);
	getRoot(u, u, u);
	cal(root);
	vis[root] = true;
	for(int i = head[root]; ~i; i = edges[i].next) {
		int v = edges[i].v;
		if(vis[v]) continue;
		divid(v);
	}
}

int main()
{
	init();
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d", &val[i]);
	}
	int u, v, w;
	for(int i = 1; i < n;  i ++) {
		scanf("%d %d %d", &u,&v,&w);
		addEdge(u, v, w);
	}
	scanf("%d", &m);
	val[0] = -1;
	for(int i = 1; i <= m; i ++) {
		scanf("%d %d", &u,&w);
		isQ[u] = true;
		ans[i] = 0;
		ques[u].push_back(std::make_pair(w, i));
	}
	divid(1);
	for(int i = 1; i <= m; i ++) {
		printf("%d\n", ans[i]);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值