主席树+树链剖分——南昌邀请赛Distance on the tree
学了差不多一星期的主席树+树链剖分,再来看这题发现其实是个板子题
一开始想复杂了,以为要用类似求树上第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的更多相关文章
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)
题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
- UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- CF487E Tourists 圆方树、树链剖分
传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...
- 2019.01.08 codeforces 1009F. Dominant Indices(长链剖分)
传送门 长链剖分模板题. 题意:给出一棵树,设fi,jf_{i,j}fi,j表示iii的子树中距离点iii距离为jjj的点的个数,现在对于每个点iii要求出使得fif_ifi取得最大值的那个jjj ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
- 计蒜客 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 ...
随机推荐
- 简单了解python使用正则表达式
正则[Regular Expression]:正则表达式通常被用来检索.替换那些符合某个模式(规则)的文本. 正则是用来干啥的:正则就是用来匹配字符串的. Python中string的几个方法: fi ...
- ISOMAP和MDS降维
转载自https://blog.csdn.net/victoriaw/article/details/78497316 核心:测地线距离(dijstra最短路径获得).MDS降维 Isomap(Iso ...
- Django相关问题
遇到models模型变动后无法用migrations生成改动后的表通过以下几个方面实现 1 python manage.py makemigrations yourapp(你改变的app) 2 p ...
- pjb fabu
#!/bin/bash PyPath=/opt/shell/mysql LocaName=`pwd` bagname=`basename $LocaName` sleep 1s ConfList=`p ...
- CENTOS手动安装修复python ,YUM
CENTOS手动安装修复YUM
CENTOS手动安装修复YUM 2019年3月8日 杨宇 Comments 0 Comment 目录 [hide] 一.问题场景 二.手动修复 2.1 下载 rpm 包 2.2 安装 rpm 包 ...
- 大规模使用 Apache Kafka 的20个最佳实践
必读 | 大规模使用 Apache Kafka 的20个最佳实践 配图来源:书籍<深入理解Kafka> Apache Kafka是一款流行的分布式数据流平台,它已经广泛地被诸如New Re ...
- 不用代码就能实现get与post
这些天在测试各种API,每次都敲代码实现,就显得有点浪费时间了 为了节约时间,提高效率,我想着收集一些可以只用 -命令行- 或者是 -浏览器- 就能够实现的技巧 在这里,我简单测试三种工具来实现 ge ...
- Spring定时器配置与运用,及Cron表达式的详解
一:首先在spring的配置文件里配置一个定时器 <task:executor id="executor" pool-size="5" /> < ...
- 3194. 【HNOI模拟题】化学(无标号无根树计数)
Problem 求\(n\)个点的每个点度数不超过\(4\)的无标号无根树个数. Data constraint \(1\le n\le 500\) Solution 尝试着把问题一般化.我们来考虑一 ...
- python模拟蒙特·卡罗法计算圆周率
蒙特·卡罗方法是一种通过概率来得到问题近似解的方法,在很多领域都有重要的应用,其中就包括圆周率近似值的计问题. 假设有一块边长为2的正方形木板,上面画一个单位圆,然后随意往木板上扔飞镖,落点坐标(x, ...