Distance on the tree(数剖 + 主席树)
题目链接: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(数剖 + 主席树)的更多相关文章
- 【洛谷2633】Count on a tree(树上主席树)
点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...
- 【BZOJ4408】[FJOI2016]神秘数(主席树)
[BZOJ4408][FJOI2016]神秘数(主席树) 题面 BZOJ 洛谷 题解 考虑只有一次询问. 我们把所有数排个序,假设当前可以表示出的最大数是\(x\). 起始\(x=0\). 依次考虑接 ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- HDU6621 K-th Closest Distance 第 k 小绝对值(主席树(统计范围的数有多少个)+ 二分 || 权值线段树+二分)
题意:给一个数组,每次给 l ,r, p, k,问区间 [l, r] 的数与 p 作差的绝对值的第 k 小,这个绝对值是多少 分析:首先我们先分析单次查询怎么做: 题目给出的数据与多次查询已经在提示着 ...
- 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)
http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...
- 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 ...
- 洛谷P4587 神秘数 [FJOI2016] 主席树
正解:主席树 解题报告: 先放下传送门QAQ 首先可以先思考如果只有一组询问,怎么解决 可以这么想,最开始一个数也麻油的时候能表示的最大的数是0嘛 然后先排个序,按顺序每次新加入一个数x,设加入这个数 ...
- BZOJ4408: [Fjoi 2016]神秘数【主席树好题】
Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = ...
随机推荐
- vim之快速查找功能
vim有强大的字符串查找功能. 我们通常在vim下要查找字符串的时候, 都是输入 / 或者 ? 加 需要查找的字符串来进行搜索,比如想搜索 super 这个单词, 可以输入 /super 或者 ...
- VirtualBox修改UUID实现虚拟硬盘的重复利用
其实,记录这个是为了留给自己看.每次用每次查,已经老到什么东西都记不住了.本次查询是从这里(VirtualBox 修改UUID实现虚拟硬盘复制)获得帮助的,感谢. 在VirtualBox把一个已经使用 ...
- 为什么很多IT公司不喜欢进过培训机构的人呢?
转载原文链接:https://www.cnblogs.com/alex3714/p/9105765.html 这几天在知乎看到一个问题“为什么很多IT公司不喜欢进过培训机构的人呢?” 身为老男孩的教学 ...
- 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!
想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了! 很多通信系统发展到某种程度都会有小型化的趋势.一方面小型化可以让系统更加轻便和有效,另一方面,日益发展的IC**技术可以用更低的成本生产 ...
- 基于Metronic的Bootstrap开发框架--工作流模块功能介绍(2)
本篇继续<基于Metronic的Bootstrap开发框架--工作流模块功能介绍>,继续介绍基于Metronic的Bootstrap开发框架的工作模块功能,介绍工作流模块中相关业务表单的界 ...
- 使用埃拉托色尼筛选法(the Sieve of Eratosthenes)在一定范围内求素数及反素数(Emirp)
Programming 1.3 In this problem, you'll be asked to find all the prime numbers from 1 to 1000. Prime ...
- python之路4-文件操作
对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 f = open('lyrics','r',encoding='utf-8') read_line = f.r ...
- js基础-字符串常用属性合集
/* * * 实例方法---->必须要通过new的方式创建的对象(实例对象)来调用的方法 * 静态方法---->直接通过大写的构造函数的名字调用的方法(直接通过大写的对象名字调 ...
- docker完整配置nginx+php+mysql
首先了解一个方法: 使用docker exec进入Docker容器 docker在1.3.X版本之后还提供了一个新的命令exec用于进入容器,这种方式相对更简单一些,下面我们来看一下该命令的使用: s ...
- js侧边菜单
目标 实现一个侧边栏菜单,最多二级,可以收起展开.用于系统左侧的主菜单. 大多数系统都会有这样的菜单,用于导航功能,切换到不同的操作页面.在单页应用系统中,菜单一般是固定在左侧,分组节点上配图标,高亮 ...