南昌网络赛 Distance on the tree 主席树+LCA

题目链接:https://nanti.jisuanke.com/t/38229
题意:给一个n个节点的树,m个询问,每次询问u到v中不大于k的边有几条
解法:LCA+主席树
网上比较流行的解法是将原树树链剖分后在原树上建主席树,事实上,本题树链剖分的目的是为了求lca,既然是为了求lca,就不需要写较为繁琐的树链剖分,我直接写了tarjan的倍增求lca的方法,然后在树上建主席树。
下一步的问题就是如何实现这个询问了,首先将所有边权离散后,用upper_bound查找第一个小于k的位置,然后问题就转化为区间第k大问题了。主席树就是为了解决这个问题的,那么如何在树上建主席树呢?主席树的insert的本质是插入当前点的后继点,那么树上的如何定义一个点的后继点呢,很自然的想到了父子结点关系,子节点即是父节点的后继点,然后就可以insert子节点来建立主席树了。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct edge
{
   
    int u,v,w;
}e[maxn<<1];
int n;
int Next[maxn<<1];
int head[maxn<<1];
int dp[maxn][20];
int dep[maxn];
int cnt;
int tot;
void add(int u,int v,int w)
{
   
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].w=w;
    Next[cnt]=head[u];
    head[u]=cnt++;
}
vector<int>vis;
struct Node
{
   
    int l,r,val;
    Node(){
   }
    Node(int a,int b,int c)
    {
   
        l=a;
        r=b;
        val=c;
    }
}node[maxn*50];
int root[maxn];
int arr[maxn];
int gettid(int num)
{
   
    return lower_bound(vis.begin
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值