离散化+权值线段树

题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于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. termux上安装lxml失败

    想试试在手机上随时可以接收到各个平台上最新的消息,于是打算在qpython上写个python的爬虫,安装bs4后,在安装lxml时出现了问题. qpython失败后,改用termux试一下,结果出现了 ...

  2. Docker-CentOS系统安装Docker

    上一节,我们介绍了安装虚拟机及操作系统,本文再详细描述安装docker的命令. 前提条件 虚拟机系统:CentOS,并且虚拟机能连通外网. 另外,虚拟机最好配置上阿里的镜像源,点此链接,进入cento ...

  3. Java 基础增强

    jdk与jre 要想深入了解Java必须对JDK的组成, 本文对JDK6里的目录做了基本的介绍,主要还是讲解 了下JDK里的各种可执行程序或工具的用途 Java(TM) 有两个平台 JRE 运行平台, ...

  4. CTE(With As)

    WITH tabdate(dt) AS ( FROM dual UNION ALL FROM tabdate WHERE dt ) SELECT * FROM TabDate ; 一.With Tab ...

  5. 如何用python无账号无限制获取企查查信息

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http ...

  6. 在学习java之余,js的使用精髓-闭包和原型链

    这里分享下廖雪峰官网写的js教程,内容写的比较实用,易懂,其中简介的原型链和闭包的知识,小伙伴们一起上呀,畅游在知识的海洋中: 地址:https://www.liaoxuefeng.com/wiki/ ...

  7. L18 批量归一化和残差网络

    批量归一化(BatchNormalization) 对输入的标准化(浅层模型) 处理后的任意一个特征在数据集中所有样本上的均值为0.标准差为1. 标准化处理输入数据使各个特征的分布相近 批量归一化(深 ...

  8. testNG 常用的注解

    常用注解介绍: @BeforeSuite 在该套件的所有测试都运行在注释的方法之前,仅运行一次 @AftereSuite 在该套件的所有测试都运行在注释方法之后,仅运行一次 @BeforeClass  ...

  9. 从一次“并发修改字段业务”引出多版本并发控制与InnoDB锁

    并发字段修改业务 最近在主要在做"工作流引擎"课题的预研工作,在涉及到"会签任务"(工作流业务概念,这与我们今天讨论文问题没有太多关联)的时候,遇到了一个并发修 ...

  10. django-admin和manage.py用法

    官网文档地址:django-admin和manage.py 金句: 所有的天赋,都来自于你对你喜欢的某种事物的模仿与学习,否则你就不会有这种天赋. 开篇话: 我们在Django开发过程中,命令行执行最 ...