题目链接:点击查看

题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数

题目分析:因为一开始不会主席树,所以就选择了线段树+离线处理,因为边权比较难处理,我就选择将边权映射到点权上,这样就将问题转换成了求u-v这条路径上权值小于等于w的点的个数了,因为涉及到了u-v这条路径,我们需要先将这条链拿出来,于是我们就选择了树链剖分,因为树上倍增不太适合这个题目,我们后续还需要对剖分的树链建立线段树,所以一开始先将给出的数剖一下,然后就是线段树离线操作的常规套路了,最后在找u-v这条路的时候一路上维护一下答案即可,有一个细节需要注意一下,也是zx学长告诉我的,因为这个题目我是将边权映射到了点权上来处理,也就导致了每个点i代表的其实是点i到点i的父亲这一条边,在树剖求路径的时候,在处理最后一段的时候,有一个地方需要加一,不然会WA,这个一会在注释里我会标记一下

因为这个题目的主流写法还是主席树,卑微的我并不会。。所以一会去学习一下主席树然后再把这个题目写一遍

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;struct qu
{int u,v,w,id;bool operator<(const qu a)const{return w<a.w;}
}q[N],edge[N];int ans[N];struct tree
{int l,r;int sum;
}tree[N<<2];struct Node
{int to,w;Node(int TO,int W){to=TO;w=W;}
};vector<Node>node[N];int deep[N],fa[N],son[N],num[N];int top[N],id[N],cnt;void dfs1(int u,int f,int dep)
{deep[u]=dep;fa[u]=f;son[u]=-1;num[u]=1;for(int i=0;i<node[u].size();i++){int v=node[u][i].to;int w=node[u][i].w;if(v==f)continue;edge[v].id=v;edge[v].w=w;dfs1(v,u,dep+1);num[u]+=num[v];if(son[u]==-1||num[son[u]]<num[v])son[u]=v;}
}void dfs2(int u,int f,int root)
{id[u]=++cnt;top[u]=root;if(son[u]!=-1)dfs2(son[u],u,root);for(int i=0;i<node[u].size();i++){int v=node[u][i].to;if(v==f||v==son[u])continue;dfs2(v,u,v);}
}void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].sum=0;if(l==r)return;int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}void update(int k,int pos)
{if(tree[k].l==tree[k].r){tree[k].sum=1;return;}int mid=tree[k].l+tree[k].r>>1;if(mid>=pos)update(k<<1,pos);elseupdate(k<<1|1,pos);tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}int query(int k,int l,int r)
{if(tree[k].r<l||tree[k].l>r)return 0;if(tree[k].l>=l&&tree[k].r<=r)return tree[k].sum;return query(k<<1,l,r)+query(k<<1|1,l,r);
}int solve(int l,int r)
{int ans=0;while(top[l]!=top[r]){if(deep[top[l]]<deep[top[r]])swap(l,r);ans+=query(1,id[top[l]],id[l]);l=fa[top[l]];}if(l==r)return ans;if(deep[l]>deep[r])swap(l,r);ans+=query(1,id[l]+1,id[r]);//这里深度小的那个点代表的是该点到该点父亲的那条边,并不属于u-v这条路径上,所以需要加一return ans;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int n,m;scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);node[u].push_back(Node(v,w));node[v].push_back(Node(u,w));}for(int i=1;i<=m;i++){scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w);q[i].id=i;}dfs1(1,0,0);dfs2(1,0,1);sort(q+1,q+1+m);sort(edge+2,edge+1+n);build(1,1,n);int pos=2;//edge数组的下标 for(int i=1;i<=m;i++){while(pos<=n&&edge[pos].w<=q[i].w)update(1,id[edge[pos++].id]);ans[q[i].id]=solve(q[i].u,q[i].v);}for(int i=1;i<=m;i++)printf("%d\n",ans[i]);return 0;
}

计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)相关推荐

  1. 【BZOJ4515】游戏,树链剖分+永久化标记线段树维护线段信息(李超线段树)

    Time:2016.05.10 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 李超线段树 一开始听faebdc讲,并没有听的很懂ww 后来找到良心博文啊有木有 折越 首先可以把修改 ...

  2. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  3. 【YBT2023寒假Day1 B】不跪模样(树链剖分)(线段树)

    不跪模样 题目链接:YBT2023寒假Day1 B 题目大意 给你一棵有根数,点有点权,两种操作: 对于所有 x 子树内与 x 距离不超过 2 的点,将其点权加 v. 询问 x 子树中,满足 i< ...

  4. 【树链剖分】【线段树】树的统计(金牌导航 树链剖分-1)

    树的统计 金牌导航 树链剖分-1 题目大意 给出一棵树,让你做若干操作,操作如下: 1.修改一个节点的值 2.查询两个节点之间路径的最大值 3.查询两个节点之间路径的和 输入样例 4 1 2 2 3 ...

  5. 计蒜客 - Distance on the tree(LCA+主席树)

    题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:多的不说了,上一个 ...

  6. 【BZOJ3531】旅行,树链剖分+开点线段树

    传送门 写在前面:为自己和并肩作战的两个队友默哀 思路:感觉做的链剖题越来越厉害了,这道题让我接触到了线段树的一种新姿势--原来写线段树,对于某个节点i,左右儿子是直接当成i∗2i*2和i∗2+1i* ...

  7. 【GDOI2016】疯狂动物城(树链剖分+可持久化线段树)

    码农题- 调了我三个晚上- 看来我的代码能力还是太弱了- 首先我们不难发现在u到v这条链的答案为∑i=1n(n−i)(n−i+1)ai2\sum_{i=1}^n\frac{(n-i)(n-i+1)a_ ...

  8. 【GXOI / GZOI2019】【树链剖分】【线段树】旧词

    [题目描述] 浮生有梦三千场 穷尽千里诗酒荒 徒把理想倾倒 不如早还乡 温一壶风尘的酒 独饮往事迢迢 举杯轻思量 泪如潮青丝留他方 --乌糟兽/愚青<旧词> 你已经解决了五个问题,不妨在这 ...

  9. BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)

    题目链接 设白色结点为未安装的软件,黑色结点为已安装的软件,则: 安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色.复杂度$O(nlog^2n)$ 卸载软件i:输出结点 ...

最新文章

  1. 从内存溢出看Java 环境中的内存结构
  2. 【错误记录】Android 分区存储下的 SD 卡应用专属外部存储空间目录访问 ( 需手动创建应用专属外部存储空间目录 )
  3. for循环里radio多选_Max里的for循环
  4. Redis常见面试题及答案模板
  5. 1071 Speech Patterns (25 分)【难度: 简单 / 知识点: 哈希表 字符串】
  6. IOS使用MessageUI Framework 发送短信息
  7. 机器学习 综合评价_PyCaret:机器学习综合
  8. 甲骨文Java 14来啦!
  9. ae插件Particle Projection for Mac(AE粒子投影插件)
  10. 一个小学教师建站的不惑与困惑
  11. HDU 2844 Coins 多重背包
  12. layui之获取form表单的radio
  13. 西岛住宿软件测试,西岛踩坑记:寄存行李居然还要收费!听说要晋升5A,你觉得呢?...
  14. 创建分布式爬虫的步骤
  15. mysql手册05_存储过程和存储函数
  16. R 计算平均值标准误差
  17. 美国自动驾驶汽车法规
  18. async/await 记录
  19. 如何解决EXCEL中弹出“信息检索”的信息
  20. 英语从句(英语兔学习笔记)

热门文章

  1. SpringCloud环境搭建
  2. springboot项目中日志分类
  3. UAA服务基础环境搭建
  4. Nacos源码集群数据同步
  5. SpringSecurity集中式整合之加入jsp
  6. hashCode和equals方法的关系
  7. Spring Cloud 版本支持
  8. Redisson框架快速入门
  9. python iloc函数_python选取特定列 pandas iloc,loc,icol的使用详解(列切片及行切片)
  10. Factory Method模式的误区:Factory Method模式是简化版的Abstract Factory吗?