离散化+权值线段树

题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于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. ElasticSearch 常用查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

  2. Java入门系列之线程池ThreadPoolExecutor原理分析思考(十五)

    前言 关于线程池原理分析请参看<http://objcoding.com/2019/04/25/threadpool-running/>,建议对原理不太了解的童鞋先看下此文然后再来看本文, ...

  3. 【从零单排HBase 03】深入HBase读写

    在了解HBase架构的基础上,我们需要进一步学习HBase的读写过程,一方面是了解各个组件在整个读写过程中充当的角色,另一方面只有了解HBase的真实请求过程,才能为后续的正确使用打下初步基础,毕竟, ...

  4. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十)之Inner Classes

    The inner class is a valuable feature because it allows you to group classes that logically belong t ...

  5. 运输层--------运输层与网络层的关系、UDP、TCP

    一.运输层与网络的区别: 网络层提供了主机之间的逻辑通信,而运输层为运行在不同主机上的进程之间提供了逻辑通信 二.实例证明: 考虑有两个家庭,一家位于美国东岸,一家位于美国西海岸,每家有12孩子.东海 ...

  6. XML布局界面

    Android推荐使用XML布局文件来定义用户界面,而不是使用Java代码来开发用户界面,因此基础所有组件都提供了两种方式来控制组件的行为:1.在XML布局文件中通过XML属性进行控制:2.在Java ...

  7. ST表(求解静态RMQ问题)

    例题:https://www.acwing.com/problem/content/1272/ ST表类似于dp. 定义st[i][j]表示以i为起点,长度位2^j的一段区间,即[ i , i + 2 ...

  8. 国产操作系统深度deepin V20体验

    1. 安装系统 国产操作系统deepin V20 bata版本已经发布.本人第一时间安装和体验.在犹豫很久之后,因为受到最新内核,高版本的bash和Python的诱惑,字体更加和谐等因素,选择升级系统 ...

  9. S7通信协议之你不知道的事儿

    在电气学习的路上,西门子PLC应该是我的启蒙PLC,从早期的S7-300/400 PLC搭建Profibus-DP网络开始接触,到后来的S7-200Smart PLC,再到现在的S7-1200/150 ...

  10. CAS原理解析

    CAS底层原理 概念 CAS的全称是Compare-And-Swap,它是CPU并发原语 它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的 CAS并发原语体现在Jav ...