学了差不多一星期的主席树+树链剖分,再来看这题发现其实是个板子题

一开始想复杂了,以为要用类似求树上第k大的树上差分思想来解决这道题,但其实树链上<=k的元素个数其实直接可以用树链剖分来求

具体是把每条树链放到主席树上询问一下求和就好了

#include<bits/stdc++.h>
using namespace std;
#define maxn 100006
struct Edge{int to,nxt,w;}edge[maxn<<];
int b[maxn],n,m,a[maxn],head[maxn],tot;
void init(){memset(head,-,sizeof head);tot=;}
void addedge(int u,int v,int w){
edge[tot].to=v;edge[tot].nxt=head[u];edge[tot].w=w;head[u]=tot++;
}
struct Node{int lc,rc,sum;}T[maxn*];
int siz,rt[maxn];
int build(int l,int r){
int now=++siz;
T[now].lc=T[now].rc=T[now].sum=;
if(l==r)return now;
int mid=l+r>>;
T[now].lc=build(l,mid);
T[now].rc=build(mid+,r);
return now;
}
int update(int last,int pos,int l,int r){//更新到pos点
int now=++siz;
T[now]=T[last];T[now].sum++;
if(l==r)return now;
int mid=l+r>>;
if(pos<=mid)T[now].lc=update(T[last].lc,pos,l,mid);
else T[now].rc=update(T[last].rc,pos,mid+,r);
return now;
}
int query(int st,int ed,int L,int R,int l,int r){
if(L<=l && R>=r)return T[ed].sum-T[st].sum;
int mid=l+r>>,res=;
if(L<=mid)res+=query(T[st].lc,T[ed].lc,L,R,l,mid);
if(R>mid)res+=query(T[st].rc,T[ed].rc,L,R,mid+,r);
return res;
} int f[maxn],son[maxn],d[maxn],size[maxn];
void dfs1(int x,int pre,int deep){
f[x]=pre;size[x]=;d[x]=deep;
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y==pre)continue;
a[y]=edge[i].w;
dfs1(y,x,deep+);
size[x]+=size[y];
if(size[y]>size[son[x]])son[x]=y;
}
}
int id[maxn],rk[maxn],idx,top[maxn];
void dfs2(int x,int tp){
top[x]=tp;id[x]=++idx;rk[idx]=x;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y!=son[x] && y!=f[x])dfs2(y,y);
}
} int Query(int x,int y,int pos){
int res=;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res+=query(rt[id[top[x]]-],rt[id[x]],,pos,,m);
x=f[top[x]];
}
if(id[x]>id[y])swap(x,y);
res+=query(rt[id[x]],rt[id[y]],,pos,,m);
return res;
}
int main(){int q;init();
cin>>n>>q;int u,v,w,k;
for(int i=;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);addedge(v,u,w);
} a[]=0x3f3f3f3f;
siz=;dfs1(,,);dfs2(,);//树剖
for(int i=;i<=n;i++)b[++m]=a[i];
sort(b+,b++m);
m=unique(b+,b++m)-(b+);
rt[]=build(,m);
for(int i=;i<=idx;i++){
int pos=lower_bound(b+,b++m,a[rk[i]])-b;
rt[i]=update(rt[i-],pos,,m);
} while(q--){
scanf("%d%d%d",&u,&v,&k);
int pos=upper_bound(b+,b++m,k)-(b+);
if(pos==){puts("");continue;}
else cout<<Query(u,v,pos)<<'\n';
}
}

主席树+树链剖分——南昌邀请赛Distance on the tree的更多相关文章

  1. 线段树&数链剖分

    傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...

  2. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  3. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  4. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  5. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  6. CF487E Tourists 圆方树、树链剖分

    传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...

  7. 2019.01.08 codeforces 1009F. Dominant Indices(长链剖分)

    传送门 长链剖分模板题. 题意:给出一棵树,设fi,jf_{i,j}fi,j​表示iii的子树中距离点iii距离为jjj的点的个数,现在对于每个点iii要求出使得fif_ifi​取得最大值的那个jjj ...

  8. 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)

    LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...

  9. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

随机推荐

  1. Oracle篇 之 多表查询

    一.概念 从多个表中查询数据时,需要在表和表间建立连接,一般使用主外键建立连接 二.连接种类 1. 等连接:连接条件使用等号 非等连接:连接条件使用等号以外的其它符号 2. 内连接:根据指定的连接条件 ...

  2. leanote使用本地账户时,去掉待同步的小红点

    切换开发者工具,如下图,点击左上角的箭头图标,选取元素,直接选择小红点. 然后会看到小红点来自于resources/app/public/themes/default.css文件中2092行: .it ...

  3. Luogu4492 [HAOI2018]苹果树 【动态规划】

    题目分析: 思路不难想,考虑三个dp状态$f,g,d$. $g[i]$表示有$i$个点的堆的数量 $d[i]$表示有$i$个点的情况下所有的方案数中点到根的距离和 $f[i]$表示要求的答案. 不难发 ...

  4. 简单记录一次getshell到进服务器的过程

    通过st2命令执行上次木马进行getshell 查看whoami,发现权限是administrator,直接net user xxx xxx123.. /add,发现拒绝访问 通过命令tasklist ...

  5. 微信小程序之:wepy(二)

    一大堆实例:人家的博客园 代码规范: 1.尽量使用驼峰命名,避免使用$开头,框架内建属性都已$开头,可以使用this直接调用. 2.入口文件.页面.组件后缀都为.wpy. 3.使用ES6语法开发. 4 ...

  6. 在maven pom.xml中加载不同的properties ,如localhost 和 dev master等jdbc.properties 中的链接不一样

    [参考]:maven pom.xml加载不同properties配置[转] 首先 看看效果: 点开我们项目中的Maven projects 后,会发现右侧 我们profile有个可勾选选项.默认勾选l ...

  7. java的集合:List、Set和Map

    虚线是接口,实线是实现类: 集合能够解决的问题:集合可以丽杰为是一种更高级的数组,可以保存多条数据 本质:java官方开发人员基于java的一些基础内容(数组等等)创建了一些接口和类,然后使用这些接口 ...

  8. 【Mac上的PotPlayer视频播放器】Movist Pro for Mac 2.1.2

    [简介] Movist 是Mac上最好用的视频播放器之一,功能齐全,类似Windows上的PotPlayer,今天和大家分享最新的 2.1.2 中文版本,Movist 支持几乎所有常见的视频格式,包括 ...

  9. 《Exception团队》第二次作业:团队项目选题报告

    一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 深入了解软件思想,强化编程技术 二.项目细则 ...

  10. 详解散列hashCode在HashMap中的使用原理

    1散列的价值在于它的速度:散列使得查询变快,它将键key保存在某处,而我们知道存储一组数组最快的数据结构是数组,所以用它来表示键的信息(注意,数组保存的是键的信息,不是键本身),由于数组是固定的,当我 ...