CF 519E(树上倍增求lca)
题意:给定一棵树,每次询问到达点u,v距离相等的点有多少个。
分析:按情况考虑:
1.abs(deep[u]-deep[v])%2==1时,必定不存在到达u,v距离相等的点。
2.如果deep[u]==deep[v]时,ans=n-num[lca(u,v)u在的儿子树]-num[lca(u,v)v在的儿子树]。
3.如果deep[u]!=deep[v]时,在u到v的路径中找出到达u,v相等的节点x,则ans=num[x]-num[u在的x儿子树].
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <map>
#define N 200010
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
struct edge
{
int v,next;
edge() {}
edge(int v,int next):v(v),next(next) {}
} e[N];
int head[N],tot;
int num[N],deep[N];
int fa[N][];
void init()
{
memset(head,-,sizeof(head));
tot=;
}
void addedge(int u,int v)
{
e[tot]=edge(v,head[u]);
head[u]=tot++;
}
void dfs(int x,int f)
{
for(int i=; i<; i++)
{
if(deep[x]<(<<i))break;
fa[x][i]=fa[fa[x][i-]][i-];
}
for(int i=head[x]; ~i; i=e[i].next)
{
int v=e[i].v;
if(v==f)continue;
fa[v][]=x;
deep[v]=deep[x]+;
dfs(v,x);
num[x]+=num[v];
}
}
int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
int t=deep[x]-deep[y];
for(int i=; i<=; i++)
if((<<i)&t)x=fa[x][i];
for(int i=; i>=; i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
if(x==y)return x;
return fa[x][];
}
int main()
{
int n,m;
while(scanf("%d",&n)>)
{
init();
for(int i=; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=;i<=n;i++)num[i]=;
deep[]=;
dfs(,);
scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%d%d", &x,&y);
if(deep[x]<deep[y])swap(x,y);
if((deep[x]-deep[y])&) printf("0\n");
else
{
int xy=lca(x, y),tx=x;
int t=(deep[x]+deep[y]-*deep[xy])/-;
for(int i=;i<;i++)if(t&(<<i))x=fa[x][i];
if(deep[tx]==deep[y])
{
t=deep[y]-deep[xy]-;
for(int i=;i<;i++)if(t&(<<i))y=fa[y][i];
printf("%d\n",n-num[x]-num[y]);
}
else printf("%d\n", num[fa[x][]]-num[x]);
}
}
}
}
CF 519E(树上倍增求lca)的更多相关文章
- [学习笔记] 树上倍增求LCA
倍增这种东西,听起来挺高级,其实功能还没有线段树强大.线段树支持修改.查询,而倍增却不能支持修改,但是代码比线段树简单得多,而且当倍增这种思想被应用到树上时,它的价值就跟坐火箭一样,噌噌噌地往上涨. ...
- 树上倍增求LCA(最近公共祖先)
前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...
- [算法]树上倍增求LCA
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
- Codeforces 609E (Kruskal求最小生成树+树上倍增求LCA)
题面 传送门 题目大意: 给定一个无向连通带权图G,对于每条边(u,v,w)" role="presentation" style="position: rel ...
- 树上倍增求LCA详解
LCA(least common ancestors)最近公共祖先 指的就是对于一棵有根树,若结点z既是x的祖先,也是y的祖先(不要告诉我你不知道什么是祖先),那么z就是结点x和y的最近公共祖先. 定 ...
- [luogu3379]最近公共祖先(树上倍增求LCA)
题意:求最近公共祖先. 解题关键:三种方法,1.st表 2.倍增法 3.tarjan 此次使用倍增模板(最好采用第一种,第二种纯粹是习惯) #include<cstdio> #includ ...
- 树上倍增求LCA
大概思想就是,节点$i$的第$2^{j}$个父节点是他第$2^{j-1}$个父亲的第$2^{j-1}$个父亲 然后可以$O(nlogn)$时间内解决…… 没了? //fa[i][j]表示i的第2^j个 ...
- 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)
洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...
随机推荐
- Android ble 蓝牙4.0 总结
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...
- Winsock基础编程
Winsock基础编程 Socket的英文原义是"孔"或"插座".作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用 ...
- Endnote X6 如何修改输出格式(output style)成为自己想要的输出格式:
Endnote X6 如何修改输出格式(output style)成为自己想要的输出格式: (1)首先尝试在endnote output style 网站中查找: http://www.endnote ...
- Qt Style Sheets Examples(QT真是有很全的文档)
http://doc.qt.io/qt-5/stylesheet-examples.html http://doc.qt.io/qt-4.8/stylesheet.html
- nyoj 55 懒省事的小明 优先队列 multiset 还有暴力
懒省事的小明 时间限制: 3000 ms | 内存限制: 65535 KB 难度: 3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的 ...
- hdu 4687 Boke and Tsukkomi
Dancing link twice. Find the maximum combination numbers in the first time. Enumerate each node, dan ...
- Android:自定义滚动边缘(EdgeEffect)效果
Android可滚动控件(GridView.ListView.ScrollView等)当用户滚动到头的时候会有个边缘反馈效果,在4.0上默认为Holo蓝色效果. 如果您的App自定义了主题颜色,比如 ...
- ASP.NET - 分页
效果: SQL-存储过程(Paging): ROW_NUMBER() over(order by MessageDateTime desc) 其中的 MessageDateTime desc 代表的 ...
- ABP分层设计
ABP分层设计 一.为什么要分层 分层架构是所有架构的鼻祖,分层的作用就是隔离,不过,我们有时候有个误解,就是把层和程序集对应起来,就比如简单三层架构中,在你的解决方案中,一般会有三个程序集项目:XX ...
- C#检查foreach为null判断
1.foreach遍历列表或数组时,如果list或数组为null,就会报错,如下图: 2.不知道微软封装foreach的为什么不先检查要遍历的对象是否为null,这样就导致,我们在写代码时,遍历列表时 ...