题目链接: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. pyinstaller 打包selenium脚本 取消cmd

    更改源代码 找到文件(selenium->webdriver->common->service.py) 添加一个参数

  2. 修改xampp-apache访问目录

    文章转自 https://my.oschina.net/u/3618644/blog/1569972 问题来源: 一般情况下,每个项目占用一个根目录,而不是一个根目录下面有多个项目. 比如说,安装xa ...

  3. .net core下用HttpClient和asp.net core实现https的双向认证

    关于https双向认证的知识可先行google,这时矸接代码. 为了双向认证,我们首先得准备两个crt证书,一个是client.crt,一个是server.crt,有时为了验证是否同一个根证书的验证, ...

  4. Linux内存管理 (9)mmap(补充)

    之前写过一篇简单的介绍mmap()/munmap()的文章<Linux内存管理 (9)mmap>,比较单薄,这里详细的梳理一下. 从常用的使用者角度介绍两个函数的使用:然后重点是分析内核的 ...

  5. Do You Kown Asp.Net Core -- Asp.Net Core 2.0 未来web开发新趋势 Razor Page

    Razor Page介绍 前言 上周期待已久的Asp.Net Core 2.0提前发布了,一下子Net圈热闹了起来,2.0带来了很多新的特性和新的功能,其中Razor Page引起我的关注,作为web ...

  6. Entity Framework Core系列之DbContext

    前言: EF Core DbContext表示与数据库的会话,并提供与数据库通信的API,具有以下功能: 数据库连接 数据操作,如查询和持久化 更改追踪 模型构建 数据映射 对象缓存 事务管理 数据库 ...

  7. 【转】shell脚本中如何传入参数

    (1)直接用$1,$2取传入的参数vim /root/test.sh#!/bin/bashif [ $1 == "start" ]  then     echo "do ...

  8. Flask 微信公众号开发

    公众号接口 1. 公众号消息会话 目前公众号内主要有这样几类消息服务的类型,分别用于不同的场景. 群发消息 公众号可以以一定频次(订阅号为每天1次,服务号为每月4次),向用户群发消息,包括文字消息.图 ...

  9. C# Note35: 异步操作

    .NET Framework 为异步操作提供了两种设计模式:使用 IAsyncResult 对象的异步操作与使用事件的异步操作. IAsyncResult 异步设计模式 通过名为 BeginOpera ...

  10. Android——具有边框的Textview

    我们可以看见很多类似瀑布流的分类: 通过边框进行选择,那么这个边框是怎么变成的呢? 我们可以通过添加背景图,不过有更加简单的,如下: 我们在drawable文件中编写一个shape, <?xml ...