【2019年ICPC南昌网络赛】Distance on the tree【DFS+线段树合并(可持久化线段树)】

2023-11-08

题目链接


DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(National Olympiad in Informatics in Provinces) in Senior High School. So when in Data Structure Class in College, he is always absent-minded about what the teacher says.

The experienced and knowledgeable teacher had known about him even before the first class. However, she didn't wish an informatics genius would destroy himself with idleness. After she knew that he was so interested in ACM(ACM International Collegiate Programming Contest), she finally made a plan to teach him to work hard in class, for knowledge is infinite.

This day, the teacher teaches about trees." A tree with nn nodes, can be defined as a graph with only one connected component and no cycle. So it has exactly n-1n−1 edges..." DSM is nearly asleep until he is questioned by teacher. " I have known you are called Data Structure Master in Graph Theory, so here is a problem. "" A tree with nn nodes, which is numbered from 11 to nn. Edge between each two adjacent vertexes uuand vv has a value w, you're asked to answer the number of edge whose value is no more than kk during the path between uu and vv."" If you can't solve the problem during the break, we will call you DaShaMao(Foolish Idiot) later on."

The problem seems quite easy for DSM. However, it can hardly be solved in a break. It's such a disgrace if DSM can't solve the problem. So during the break, he telephones you just for help. Can you save him for his dignity?

Input

In the first line there are two integers n,mn,m, represent the number of vertexes on the tree and queries(2 \le n \le 10^5,1 \le m \le 10^52≤n≤105,1≤m≤105)

The next n-1n−1 lines, each line contains three integers u,v,wu,v,w, indicates there is an undirected edge between nodes uu and vv with value ww. (1 \le u,v \le n,1 \le w \le 10^91≤u,v≤n,1≤w≤109)

The next mm lines, each line contains three integers u,v,ku,v,k , be consistent with the problem given by the teacher above. (1 \le u,v \le n,0 \le k \le 10^9)(1≤u,v≤n,0≤k≤109)

Output

For each query, just print a single line contains the number of edges which meet the condition.


  题意:有N-1条边,构成u - v边权为w的这样子的组成的一棵树,然后有Q次询问,问的是u - v这条链上小于等于W的值的数量是多少。

  思路:没必要再去离散化了,直接去将右区间开到1e9即可了,然后就是子节点的树合并父亲节点的树,并且还要再加上一个自己的到父节点的边权的值进去,普通的可持久化线段树思维。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define efs 1e-8
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7, _UP = 1e9;
int N, Q, head[maxN], cnt, deep[maxN], fa[maxN][25], root[maxN], tot;
struct Eddge
{
    int nex, to, val;
    Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), val(c) {}
}edge[maxN<<1];
inline void addEddge(int u, int v, int val)
{
    edge[cnt] = Eddge(head[u], v, val);
    head[u] = cnt++;
}
inline void _add(int u, int v, int val) { addEddge(u, v, val); addEddge(v, u, val); }
int tree[40 * maxN], lc[40 * maxN], rc[40 * maxN];
inline void pushup(int rt) { tree[rt] = tree[lc[rt]] + tree[rc[rt]]; }
inline void insert(int &rt, int l, int r, int qx)
{
    if(!rt) rt = ++tot;
    tree[rt]++;
    if(l == r) return;
    int mid = HalF;
    if(qx <= mid) insert(lc[rt], l, mid, qx);
    else insert(rc[rt], mid + 1, r, qx);
    pushup(rt);
}
inline void Merge(int rt, int old, int l, int r)
{
    if(l == r) { tree[rt] = tree[rt] + tree[old]; return; }
    int mid = HalF;
    if(lc[rt] && lc[old]) Merge(lc[rt], lc[old], l, mid);
    else if(lc[old]) lc[rt] = lc[old];
    if(rc[rt] && rc[old]) Merge(rc[rt], rc[old], mid + 1, r);
    else if(rc[old]) rc[rt] = rc[old];
    pushup(rt);
}
inline int Query(int rt, int l, int r, int ql, int qr)
{
    if(!rt) return 0;
    if(ql <= l && qr >= r) return tree[rt];
    int mid = HalF;
    if(qr <= mid) return Query(lc[rt], l, mid, ql, qr);
    else if(ql > mid) return Query(rc[rt], mid + 1, r, ql, qr);
    else return Query(lc[rt], l, mid, ql, qr) + Query(rc[rt], mid + 1, r, ql, qr);
}
inline void dfs(int u, int father, int depth)
{
    deep[u] = depth;
    fa[u][0] = father;
    Merge(root[u], root[father], 0, _UP);
    for(int i=head[u], v, c; ~i; i=edge[i].nex)
    {
        v = edge[i].to; c = edge[i].val;
        if(v == father) continue;
        insert(root[v], 0, _UP, c);
        dfs(v, u, depth + 1);
    }
}
inline void pre_LCA()
{
    for(int j=0; (1<<(j + 1)) < N; j++)
    {
        for(int i=1; i<=N; i++)
        {
            if(fa[i][j] < 0) fa[i][j + 1] = -1;
            else fa[i][j + 1] = fa[fa[i][j]][j];
        }
    }
}
int LCA(int u, int v)
{
    if(deep[u] > deep[v]) swap(u, v);
    int tmp = deep[v] - deep[u];
    for(int i=0; (1<<i) <= tmp; i++) if( (tmp >> i) & 1) v = fa[v][i];
    if(u == v) return u;
    for(int i=log2(1. * N); i>=0; i--)
    {
        if(fa[u][i] != fa[v][i])
        {
            u = fa[u][i];
            v = fa[v][i];
        }
    }
    return fa[u][0];
}
inline void init()
{
    cnt = tot = 0;
    memset(head, -1, sizeof(head));
    memset(fa, -1, sizeof(fa));
    memset(tree, 0, sizeof(tree));
    memset(lc, 0, sizeof(lc));
    memset(rc, 0, sizeof(rc));
    for(int i=1; i<=N; i++) root[i] = 0;
}
int main()
{
    scanf("%d%d", &N, &Q);
    init();
    for(int i=1, u, v, w; i<N; i++)
    {
        scanf("%d%d%d", &u, &v, &w);
        _add(u, v, w);
    }
    dfs(1, 1, 0);
    pre_LCA();
    int u, v, w, ff;
    while(Q--)
    {
        scanf("%d%d%d", &u, &v, &w);
        ff = LCA(u, v);
        printf("%d\n", Query(root[u], 0, _UP, 0, w) + Query(root[v], 0, _UP, 0, w) - 2 * Query(root[ff], 0, _UP, 0, w));
    }
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【2019年ICPC南昌网络赛】Distance on the tree【DFS+线段树合并(可持久化线段树)】 的相关文章

随机推荐

  • 标准签到题

    链接 https ac nowcoder com acm contest 6840 H 来源 牛客网 题目描述 在大家的努力下 终于要进行第一届ACM集训队的选拔赛了 华华和辉辉商议了一下 准备一起给这次比赛出题 那么既然是比赛 为了不难为
  • cout顺序,i++和++i,*p++和*++p

    1 cout输出流顺序 cout是从右到左读取参数 如果参数是函数 则先执行函数体 再将返回的值压栈 否则直接将值压栈 最后再将栈中的值输出来 include
  • 【ChatGPT】用ChatGPT和通义千问写2023年高考语文作文——全国甲卷

    试题内容 阅读下面的材料 根据要求写作 60分 人们因技术发展得以更好地掌控时间 但也有人因此成了时间的仆人 这句话引发了你怎样的联想与思考 请写一篇文章 要求 选准角度 确定立意 明确文体 自拟标题 不要套作 不得抄袭 不得泄露个人信息
  • 题目 1017: [编程入门]完数的判断

    题目描述 一个数如果恰好等于不包含它本身所有因子之和 这个数就称为 完数 例如 6的因子为1 2 3 而6 1 2 3 因此6是 完数 编程序找出N之内的所有完数 并按下面格式输出其因子 核心和关键是如何求因数 双循环 使用if i j 0
  • Redis集群方案及实现

    之前做了一个Redis的集群方案 跑了小半年 线上运行的很稳定 差不多可以跟大家分享下经验 前面写了一篇文章 数据在线服务的一些探索经验 可以做为背景阅读 应用 我们的Redis集群主要承担了以下服务 1 实时推荐 2 用户画像 3 诚信分
  • 扩展欧几里得算法求特解以及通解

    扩展欧几里得算法 裴蜀定理 百度百科上的解释 裴蜀定理 或贝祖定理 得名于法国数学家艾蒂安 裴蜀 说明了对任何整数a b和它们的最大公约数d 关于未知数x和y的线性不定方程 称为裴蜀等式 若a b是整数 且gcd a b d 那么对于任意的
  • 软件测试报告包含哪些内容?

    软件测试报告一般包含以下内容 1 引言 目的 背景 缩略语 参考文献 2 测试概述 测试目的 项目介绍 测试目标 3 测试资源 测试人员 测试软硬件环境及配置 测试环境的网络拓扑 4 测试参考资料 在测试过程中所参考的文献资料等 5 测试进
  • moviepy简介及安装

    专栏 Python基础教程目录 专栏 使用PyQt开发图形界面Python应用 专栏 PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一 概述 MoviePy是一个用于视频编辑的Python模块 可用于进行视频的基本操作 如
  • 特征工程(补充)--特征组合

    特征组合变化也属于特征选择的一种手段 这部分工作可发挥的空间就看你的想像力和经验了 这里的组合变化远不限于把已有的特征加减乘除 比如Kernel Tricks之类 举个比较有想像力的例子 现在市面上社交网络里面 你可能认识的人 的推荐算法几
  • 用通俗易懂的方式讲解大模型分布式训练并行技术:概述

    近年来 随着Transformer MOE架构的提出 使得深度学习模型轻松突破上万亿规模参数 传统的单机单卡模式已经无法满足超大模型进行训练的要求 因此 我们需要基于单机多卡 甚至是多机多卡进行分布式大模型的训练 而利用AI集群 使深度学习
  • linux配置sonarqube遇到的坑

    1 9000端口开了 sonar配置的9000端口 但是连接失败 sonar localhost linux x86 64 curl http localhost 9000 curl 7 Failed connect to localhos
  • Python记4(NumPy计算库

    目录 1 安装NumPy库 2 数组属性 3 创建数组 array 列表 或者array 元组 3 1 多维数组 3 2 数据类型 3 3 创建特殊的数组 3 4 asarray 将列表或元组转化为数组对象 3 5改变数组形状 reshap
  • c++ static修饰变量、函数、对象、数组

    文章目录 static相关语法 一 static 修饰变量 修饰局部变量 修饰全局变量 修饰类中变量 内存初始化时机 二 static修饰函数 修饰普通函数 全局静态函数 修饰类中的函数 静态成员函数 三 static修饰类对象 stati
  • CSS解决高度自适应问题

    高度自适应问题 我很抵触用js去解决 因为不好维护 也不够自然 但是纯用CSS 难度不小 比如下面我要说的例子 需求 1 这个矩形的高度和浏览器窗口的高度相同 不能出现纵向滚动条 2 绿色部分高度固定 比如50px 3 紫色部分填充剩余的高
  • 32位/64位WINDOWS驱动之保护特定名字进程【蓝屏修复】

    32位 64位WINDOWS驱动之保护特定名字进程 蓝屏修复 1 驱动层 进程保护 c 在const char PsGetProcessImageFileName PEPROCESS arg1 下添加 功能 进程ID 进程名称 const
  • Nginx 反向代理 proxy_pass 规则配置

    Nginx 其中一个作用是反向代理 有的时候 需要将某个请求转发到另外的地址做其他用途 基于某些原因 原请求地址 可能是比较长的 具体的请求地址 且不方便修改 因此需要在 proxy pass 中配置规则 用以满足条件 转发 Nginx p
  • IPtables之一:基本概念介绍

    原文地址 http www 2cto com Article 201207 142771 html 防火墙按照实现方法可以分为软件防火墙和硬件防火墙 纯硬件防火墙是很少的 一般见到的防火墙设备都是依靠软件搭配实现 按照功能可以将防火墙分为包
  • 办公技能(PPT、Word、Excel、Access、superset、pyecharts)

    一 superset学习 https blog csdn net seek97 article details 109552886 spm 1001 2014 3001 5501 二 pyecharts https gallery pyec
  • CNDS博客等级

    CNDS博客积分规则 博客积分是CSDN对用户努力的认可和奖励 也是衡量博客水平的重要标准 博客等级也将由博客积分唯一决定 积分规则具体如下 1 每发布一篇原创或者翻译文章 可获得10分 2 每发布一篇转载文章 可获得2分 3 博主的文章每
  • 【2019年ICPC南昌网络赛】Distance on the tree【DFS+线段树合并(可持久化线段树)】

    题目链接 DSM Data Structure Master once learned about tree when he was preparing for NOIP National Olympiad in Informatics i