题目链接: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. day15-面向对象基础(二)

    今天整理类的组合以及类的三大特性 1.类的组合 2.类的继承 3.类的封装 4.类的多态 开始今日份整理 1.类的组合 类与类之间,并不是独立的,很多的时候在正常使用的时候都是类与类之间互相调用,所以 ...

  2. SP11470 TTM - To the moon

    嘟嘟嘟 主席树+区间修改. 以为是水题,写着写着发现区间修改标记下传会出问题,然后想了想发现以前做的只是单点修改. 那怎么办咧? 然后题解交了我标记永久化这个神奇的东西. 特别好理解,就是修改的时候直 ...

  3. Spring Security(三十五):Part III. Testing

    This section describes the testing support provided by Spring Security. 本节介绍Spring Security提供的测试支持. ...

  4. Windows将自己的代码发布到Github上

    1.在GitHub上创建一个repository 2.在自己的电脑上选择工作的文件夹使用Git Bash clone刚刚创建的repository 3.此时本地git应该已经连接了GitHub,如果没 ...

  5. .net core EF的简单使用

    1.在mysql中新建一个表 2.在控制台中装个EF包  Install-Package Pomelo.EntityFrameworkCore.MySql 3.新建一个Person类 4.创建DbCo ...

  6. element ui 时间 date 差一天

    let BirthdayYMD = common.formatDate(this.addForm.Dendline); this.addForm.Dendline = new Date(Birthda ...

  7. 使用tar解压的时候提示:gzip: stdin: not in gzip format

    问题背景 我是在CentOS上面使用wget命令下载JDK8的源码之后,使用tar命令解压下载的文件,结果出现这样的错误: [root@VM_0_8_centos src]# wget https:/ ...

  8. jQuery 事件绑定

    在文档装载完成后,如果打算为元素绑定事件来完成某些操作,则可以使用 bind() 方法来对匹配元素进行特定事件的绑定,bind() 方法的调用格式为:bind( type [, data] , fn ...

  9. 返回通知 对方法返回的结果可以进行加工 例如请求接口后 返回的json参数可以加工成对象返回给调用者

  10. [模板] 杜教筛 && bzoj3944-Sum

    杜教筛 浅谈一类积性函数的前缀和 - skywalkert's space - CSDN博客 杜教筛可以在\(O(n^{\frac 23})\)的时间复杂度内利用卷积求出一些积性函数的前缀和. 算法 ...