题目链接:https://nanti.jisuanke.com/t/38229

题目大意:给你n个点,n-1条边,然后是m次询问,每一次询问给你u,v,w然后问你从u -> v 的路径上有多少边是小于等于w的、

AC代码:

 #include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<stdio.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
# define inf 0x3f3f3f3f
# define ll long long
const int maxn = 3e5+;
int n,m,num,tot,cnt,totn;
int a[maxn];
int head[maxn];
int root[maxn];
struct Query
{
int l,r,tt;
} que[maxn];
struct Tree
{
int ls,rs,sum;
} tr[maxn*];
struct Edge
{
int from,to,val,s;
} edges[maxn<<];
void addedge(int x,int y,int z)
{
edges[++tot]=Edge{x,y,z,head[x]};
head[x]=tot;
}
int d[maxn],fa[maxn],size[maxn],w[maxn];
int son[maxn];
int rk[maxn],kth[maxn],top[maxn];
void dfs1(int u,int pre,int val)
{ d[u]=d[pre]+;
fa[u]=pre;
size[u]=;
w[u]=val;
for(int i=head[u]; i!=-; i=edges[i].s)
{
Edge &e=edges[i];
if(e.to==pre)
continue;
dfs1(e.to,u,e.val);
size[u]+=size[e.to];
if(size[e.to]>size[son[u]])
son[u]=e.to;
}
}
void dfs2(int u,int y)
{
rk[u]=++cnt;
kth[cnt]=u;
top[u]=y;
if(son[u]==)
return ;
dfs2(son[u],y);
for(int i=head[u]; i!=-; i=edges[i].s)
{
Edge &e=edges[i];
if(e.to==son[u]||e.to==fa[u])
continue;
dfs2(e.to,e.to);
}
}
void buildtree(int &x,int l,int r)
{
x=++totn;
if(l==r)
return ;
int mid=(l+r)>>;
buildtree(tr[x].ls,l,mid);
buildtree(tr[x].rs,mid+,r);
}
void add(int &x,int last,int l,int r,int p)
{
x=++totn;
tr[x]=tr[last];
if(l==r)
{
tr[x].sum++;
return ;
}
int mid=l+r>>;
if(p<=mid)
add(tr[x].ls,tr[last].ls,l,mid,p);
if(p> mid)
add(tr[x].rs,tr[last].rs,mid+,r,p);
tr[x].sum=tr[tr[x].ls].sum+tr[tr[x].rs].sum;
}
int ask(int ql,int qr,int l,int r,int kk)
{
if(<=l&&r<=kk)
return tr[qr].sum-tr[ql].sum;
int mid=l+r>>,ans=;
if(<=mid)
ans+=ask(tr[ql].ls,tr[qr].ls,l,mid,kk);
if(mid<kk)
ans+=ask(tr[ql].rs,tr[qr].rs,mid+,r,kk);
return ans;
}
int get_sum(int x,int y,int tt)
{
int ans=;
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(d[fx]<d[fy])
swap(x,y),swap(fx,fy);
ans+=ask(root[rk[fx]-],root[rk[x]],,num,tt);
x=fa[fx];
fx=top[x];
}
if(d[x]<d[y])
swap(x,y);
ans+=ask(root[rk[y]],root[rk[x]],,num,tt);
return ans;
}
int main()
{
scanf("%d %d",&n,&m);
ll x,y,z,id,ans;
for(int i=; i<=n; i++)
{
head[i]=-;
}
for(int i=; i<=n-; i++)
{
scanf("%d %d %d",&x,&y,&z);
a[++num]=z;
addedge(x,y,z);
addedge(y,x,z);
}
for(int i=; i<=m; i++)
{
scanf("%d %d %d",&que[i].l,&que[i].r,&que[i].tt);
a[++num]=que[i].tt;
}
sort(a+,a+num+);
num=unique(a+,a+num+)-a-;
dfs1(,,inf);
dfs2(,);
for(int i=; i<=n; i++)
{
w[i]=lower_bound(a+,a+num+,w[i])-a;
}
buildtree(root[],,num);
for(int i=; i<=n; i++)
{
add(root[i],root[i-],,num,w[kth[i]]);
}
for(int i=; i<=m; i++)
{
que[i].tt=lower_bound(a+,a+num+,que[i].tt)-a;
int ans=get_sum(que[i].l,que[i].r,que[i].tt);
printf("%d\n",ans);
}
return ;
}

Distance on the tree(数剖 + 主席树)的更多相关文章

  1. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  2. BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树

    BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...

  3. 【BZOJ4408】[FJOI2016]神秘数(主席树)

    [BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...

  4. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  5. HDU6621 K-th Closest Distance 第 k 小绝对值(主席树(统计范围的数有多少个)+ 二分 || 权值线段树+二分)

    题意:给一个数组,每次给 l ,r, p, k,问区间 [l, r] 的数与 p 作差的绝对值的第 k 小,这个绝对值是多少 分析:首先我们先分析单次查询怎么做: 题目给出的数据与多次查询已经在提示着 ...

  6. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  7. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  8. 洛谷P4587 神秘数 [FJOI2016] 主席树

    正解:主席树 解题报告: 先放下传送门QAQ 首先可以先思考如果只有一组询问,怎么解决 可以这么想,最开始一个数也麻油的时候能表示的最大的数是0嘛 然后先排个序,按顺序每次新加入一个数x,设加入这个数 ...

  9. BZOJ4408: [Fjoi 2016]神秘数【主席树好题】

    Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = ...

随机推荐

  1. 文本分类实战(八)—— Transformer模型

    1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...

  2. SDOI 2019 R1游记

    $SDOI$ $2019$ $R1$游记 昨天才刚回来,今天就来写游记啦! Day -5: 做了一下去年省选的Day1,感觉很神仙. Day -4: 做了一下去年省选的Day2,感觉还是很神仙. Da ...

  3. linux用户身份和文件权限

    1.用户身份与能力 root管理员是linux 的超级用户,他拥有系统的所有权,能够管理系统的各项功能,如添加/删除用户,启动/关闭服务进程,开启/禁用硬件设备…… "Linux系统中的管理 ...

  4. [详细实例]MicroPython拼插编程实战:DIY一台会思考的壁障车

    (转载请注明文章来源,更多教程可自助参考www.tpyboard.com,QQ技术交流群:157816561,公众号:MicroPython玩家汇) 在日常生活中,大家会经常见到各种各样的遥控车,它需 ...

  5. Kafka--消息队列

    说明:解耦指的是客户端A和客户端B不需要同步,两者之间的通信是异步的:消息队列是可以复制备份的,因此消息队列具有冗余性和可恢复性:所谓拓展性指的是,在大型分布式系统中,消息队列是分布在集群中的:队列是 ...

  6. Python——Flask框架——程序的结构

    一.项目结构 |-flasky |-app Flask程序一般都保存在这里 |-templates/ |-static/ |main/ |-__init__.py |-errors.py |-form ...

  7. iOS高德地图让指定区域或者点显示在屏幕中间

    对于高德地图也是一个新手,很多功能看文档,问技术 或者高德群里讨论  群号:204668425 在我们需求中绘制的有 圆 折线 不规则图形 方式,打开地图指定的绘制图形置于屏幕中间 1.首先创建一个数 ...

  8. Java拓展接口-default关键词

    Java接口在使用过程中有两点规定: 1.接口中只能有定义方法名.方法返回类型,不能有方法的实现. 2.实现接口的类,必须实现接口中所有的方法. 例如下面的例子: //定义接口 public inte ...

  9. DRF之版本控制、认证和权限组件

    一.版本控制组件 1.为什么要使用版本控制 首先我们开发项目是有多个版本的当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了像bootstrap有2.3.4版本的 ...

  10. centos安装node环境

    一.安装wget yum install -y wget 二.下载node最新的安装包 wget https://nodejs.org/dist/v10.13.0/node-v10.13.0-linu ...