离散化+权值线段树

题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度。

这个题目和之前写的那个给你一棵树询问这棵树的这个节点到根节点之间的节点权重相乘小于等于k的对数非常像。

之前是不是就是放进去弹出来的操作,这个也是一样,之前用的是离散化逆序对的思想来求,这个开始没有想到。

然后自己写了一个很暴力的线段树,线段树要是没有一个连续的区间是有很高复杂度的。

所以要想办法把这个转化成一个连续的区间,这个和上面一样通过逆序对的思想也可以转化成一个连续的区间。

首先把这个数进行离散化,然后建树,最后就是dfs序+线段树。

我这么写要注意初始化,因为可能是在根节点1 的时候询问,这个就不会在后面被考虑到,所以输出这个数组要初始化为-1

然后我出了一个在query这里,id<<1,忘记了 |1,

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
#include <iostream>
#include <algorithm>
#define debug(n) printf("%d\n",n)
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
int n, out[maxn], b[maxn], len;
struct node {
int v;
int w;
node(int v = , int w = ) :v(v), w(w) {}
};
struct edge {
int w;
int id;
edge(int w = , int id = ) :w(w), id(id) {}
};
vector<node>G[maxn];
vector<edge>e[maxn];
int sum[maxn * ], maxx[maxn * ]; void push_up(int id) {
sum[id] = sum[id << ] + sum[id << | ];
maxx[id] = max(maxx[id << ], maxx[id << | ]);
// printf("maxx[%d]=%d\n",id,maxx[id]);
} void update(int id, int l, int r, int pos, int val) {
// printf("id=%d l=%d r=%d pos=%d val=%d\n", id, l, r, pos, val);
if (l == r) {
sum[id] += val;
if (sum[id]) maxx[id] = l;
else maxx[id] = ;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos, val);
else update(id << | , mid + , r, pos, val);
push_up(id);
} int query(int id, int l, int r, int x, int y) {
if (x <= l && y >= r) return maxx[id];
int mid = (l + r) >> ;
int ans = ;
// printf("id=%d x=%d y=%d\n",id,x,y);
if (x <= mid) ans = max(ans, query(id << , l, mid, x, y));
// cout<<x<<' '<<y<<endl;
if (y > mid) ans = max(ans, query(id << | , mid + , r, x, y));
// printf("!!id=%d ans=%d x=%intd y=%intd mid=%d\n", id, ans,x,y,mid); return ans;
} void dfs(int u, int pre) {
for (int i = ; i < G[u].size(); i++) {
node now = G[u][i];
if (now.v == pre) continue;
int t = lower_bound(b + , b + + len, now.w) - b;
update(, , len, t, );
// printf("www now.v=%d t=%d\n",now.v,t);
for (int j = ; j < e[now.v].size(); j++) {
edge x = e[now.v][j];
int t1 = upper_bound(b + , b + + len, x.w) - b - ;
int ans = ;
if (t1 <= ) {
// cout<<x.id<<'!'<<endl;
out[x.id] = -;
}
else {
// printf("t1=%d\n",t1);
ans = query(, , len, , t1);
if (ans == ) out[x.id] = -;
else out[x.id] = b[ans];
}
}
dfs(now.v, u);
update(, , len, t, -);
// printf("qqq now.v=%d t=%d\n",now.v,t);
}
} int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = ; i <= n; i++) G[i].clear(), e[i].clear();
for (int i = ; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u].push_back(node(v, w));
G[v].push_back(node(u, w));
b[i] = w;
}
sort(b + , b + n);
len = unique(b + , b + n) - b - ;
memset(sum, , sizeof(sum));
memset(maxx, , sizeof(maxx));
int q;
scanf("%d", &q);
for (int i = ; i <= q; i++) {
int u, w;
scanf("%d%d", &u, &w);
e[u].push_back(edge(w, i));
}
memset(out, -, sizeof(out));
dfs(, -);
for (int i = ; i <= q; i++) printf("%d\n", out[i]);
}
return ;
}
/*
4
5
1 2 2
1 3 4
2 4 6
2 5 8
2
3 4
2 2
*/

线段树+dfs序

S - Query on a tree HDU - 3804 线段树+dfs序的更多相关文章

  1. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  2. hdu 5039 线段树+dfs序

    http://acm.hdu.edu.cn/showproblem.php?pid=5039 给定一棵树,边权为0/1.m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数. 用树形df ...

  3. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  4. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  5. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  6. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  7. HDU 6191 Query on A Tree(可持久化Trie+DFS序)

    Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Othe ...

  8. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  9. CF620E New Year Tree 线段树 dfs序

    luogu链接 题目大意: 有一个节点有颜色的树 操作1.修改子树的颜色 操作2.查询子树颜色的种类 注意,颜色种类小于60种 只有子树的操作,dfs序当然是最好的选择 dfs序列是什么,懒得讲了,自 ...

随机推荐

  1. Linux c++ vim环境搭建系列(4)——vim插件安装配置使用

    4. 插件 主要是c++相关的. ~/.vimrc文件在GitHub上有:https://github.com/whuwzp/vim_config 以下内容参考: https://github.com ...

  2. java异常处理:finally中不要return

    java异常处理:finally中不要return 复制代码 public class Ex1 { public static void main(String[] args) { System.ou ...

  3. 绕过CDN查找真实 IP 姿势总结

    返回域名解析对应多个 IP 地址,网站可能部署CDN业务,我们就需要bypass CDN,去查找真正的服务器ip地址 0x01.域名搜集 由于成本问题,可能某些厂商并不会将所有的子域名都部署 CDN, ...

  4. Xshell远程连接Linux系统

    一般来说我们连接Linux,会使用到一些远程连接工具 比如:Xshell和Xftp Xshell:远程连接linux系统 Xftp:远程在Linux系统中上传或下载文件 Xshell和Xftp百度云链 ...

  5. TCP基础概念

    定义 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议 特点 TCP是一种面向广域网的通信协议,目的是在跨越多个网 ...

  6. Laravel异步队列全攻略

    最近项目需求,研究了laravel的异步队列.官方文档虽然很是详细,但也有些晦涩难懂,在此记录下步骤,供大家参考. 1.修改/config/queue.php文件 <?php return [ ...

  7. billu b0x2靶机渗透

    实战渗透靶机billu b0x2 攻击kali :192.168.41.147 靶机b0x2: 192.168.41.148 起手先nmap扫了一下 扫到了四个开放的端口,有ssh,http,rpcb ...

  8. Servlet 和 Servlet容器

    Servlet 很多同学可能跟我一样始终没有搞清楚到底什么是 Servlet,什么是 Servlet 容器.网上看了很多帖子,或许人家说的很清楚,但是自己的那个弯弯就是拐不过来. 想了很久说一下自己的 ...

  9. 优质中文NLP资源集合,做项目一定用得到!

    今天要给大家在推荐 Github 上一个优质的中文 NLP 工具和资源集合项目——funNLP,已经获得了 5.3k Stars,1k+ Forks. 项目作者 杨洋,一枚水博&互联网民工,目 ...

  10. react: typescript integrate withRouter

    define interface: export interface INav { nav: string } export interface IModuleItem { state?: strin ...