A and B and Lecture Rooms(LCA)
题目描述
A and B are preparing themselves for programming contests.
The University where A and B study is a set of rooms connected by corridors. Overall, the University has n rooms connected by n - 1 corridors so that you can get from any room to any other one by moving along the corridors. The rooms are numbered from 1 to n.
Every day А and B write contests in some rooms of their university, and after each contest they gather together in the same room and discuss problems. A and B want the distance from the rooms where problems are discussed to the rooms where contests are written to be equal. The distance between two rooms is the number of edges on the shortest path between them.
As they write contests in new rooms every day, they asked you to help them find the number of possible rooms to discuss problems for each of the following m days.
Input
The first line contains integer n (1 ≤ n ≤ 105) — the number of rooms in the University.
The next n - 1 lines describe the corridors. The i-th of these lines (1 ≤ i ≤ n - 1) contains two integers ai and bi (1 ≤ ai, bi ≤ n), showing that the i-th corridor connects rooms ai and bi.
The next line contains integer m (1 ≤ m ≤ 105) — the number of queries.
Next m lines describe the queries. The j-th of these lines (1 ≤ j ≤ m) contains two integers xj and yj (1 ≤ xj, yj ≤ n) that means that on the j-th day A will write the contest in the room xj, B will write in the room yj.
Output
In the i-th (1 ≤ i ≤ m) line print the number of rooms that are equidistant from the rooms where A and B write contest on the i-th day.
Examples
4
1 2
1 3
2 4
1
2 3
1
4
1 2
2 3
2 4
2
1 2
1 3
0
2
解析:
给出树上两点u,v,找到与u,v距离相等的点的个数
先找到u,v的公共祖先r,然后知道u,v间的距离,中间位置为mid;
当然若dis(u,v)为奇数则无解;
将mid的位置进行讨论:
mid在r上:
mid不在r上:
//毒瘤题
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
vector<int>G[];
int n,m;
int size[],grand[][],deep[];
//数据范围、数组范围要注意
void build(int x,int pre)
{
for(int i=;i<=;i++)
{
grand[x][i]=grand[grand[x][i-]][i-];
}
size[x]=;
for(int i=;i<G[x].size();i++)
{
int v=G[x][i];
if(v==pre)continue;
deep[v]=deep[x]+;
grand[v][]=x;
build(v,x);
size[x]+=size[v];
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
int dis=deep[u]-deep[v];
///////////////////////////////////
for(int k=;k<;k++){
if((dis>>k)&){
u=grand[u][k];
}
}
//把u调到和v同一深度
///////////////////////////////////
if(u==v)return u;//当且只当u、v处于一条链时
for(int k=;k>=;k--){
if(grand[u][k]!=grand[v][k]){
u=grand[u][k];
v=grand[v][k];
}
}
return grand[u][];
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v;scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);//vector可以...节约代码量
}
build(,);//建树
scanf("%d",&m);//m个询问
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
int r=lca(u,v);
int dis=deep[u]+deep[v]-*deep[r];
if(dis&){printf("0\n");}
if(deep[u]>deep[v])swap(u,v);
else
{
dis/=;
/////////////////////////////////////////////////
int mid=v;
for(int k=;k>=;k--){
if((dis>>k)&) mid=grand[mid][k];
}
/////////////////////////找到 mid
int ans=;
if(mid==r)
{
int preu=u,prev=v;
int du=deep[u]-deep[r];du--;
int dv=deep[v]-deep[r];dv--;
for(int k=;k>=;k--){
if((du>>k)&) preu=grand[preu][k];
if((dv>>k)&) prev=grand[prev][k];
}
ans=n-size[preu]-size[prev];
}
else
{
int prev=v,preu=u;
int dv=deep[v]-deep[mid];
dv--;
for(int k=;k>=;k--){
if((dv>>k)&) prev=grand[prev][k];
}
ans=size[mid]-size[prev];
}
cout<<ans<<endl;
}
}
}
A and B and Lecture Rooms(LCA)的更多相关文章
- codeforces 519E A and B and Lecture Rooms LCA倍增
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Submit Status Prac ...
- codeforces 519E A and B and Lecture Rooms(LCA,倍增)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud E. A and B and Lecture Rooms A and B are ...
- Codeforces Round #294 (Div. 2) A and B and Lecture Rooms(LCA 倍增)
A and B and Lecture Rooms time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- [CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】
题目链接:E. A and B and Lecture Rooms 题目大意 给定一颗节点数10^5的树,有10^5个询问,每次询问树上到xi, yi这两个点距离相等的点有多少个. 题目分析 若 x= ...
- Codeforces 519E A and B and Lecture Rooms [倍增法LCA]
题意: 给你一棵有n个节点的树,给你m次询问,查询给两个点,问树上有多少个点到这两个点的距离是相等的.树上所有边的边权是1. 思路: 很容易想到通过记录dep和找到lca来找到两个点之间的距离,然后分 ...
- [codeforces 519E]E. A and B and Lecture Rooms(树上倍增)
题目:http://codeforces.com/problemset/problem/519/E 题意:给你一个n个点的树,有m个询问(x,y),对于每个询问回答树上有多少个点和x,y点的距离相等 ...
- Codeforces 519 E. A and B and Lecture Rooms
Description 询问一个树上与两点距离相等的点的个数. Sol 倍增求LCA. 一棵树上距离两点相等,要么就只有两点的中点,要么就是与中点相连的所有点. 有些结论很容易证明,如果距离是偶数,那 ...
- Codeforces 519E A and B and Lecture Rooms
http://codeforces.com/contest/519/problem/E 题意: 给出一棵树和m次询问,每次询问给出两个点,求出到这两个点距离相等的点的个数. 思路: lca...然后直 ...
- Codeforces519 E. A and B and Lecture Rooms
传送门:>Here< 题意:询问给出一棵无根树上任意两点$a,b$,求关于所有点$i$,$dist(a,i) = dist(b,i)$的点的数量.要求每一次询问在$O(log n)$的时间 ...
随机推荐
- Orm 常见查询实例
一.Moon.Orm框架总述 (您还用hibernate?实体框架?) 1.框架名:Moon 意思是月亮,而非Mono.因为很喜欢明月,所以以此为名.它是一个.NET下的Orm框架. 2.发展历史:历 ...
- Ognl 使用实例手册
上一篇博文介绍了ongl的基础语法,接下来进入实际的使用篇,我们将结合一些实际的case,来演示ognl究竟可以支撑到什么地步 在看本文之前,强烈建议先熟悉一下什么是ognl,以及其语法特点,减少阅读 ...
- AKKA事件机制
AKKA Event Bus 事件机制就用于当前运行环境,与集群环境不同,详细见AKKA 集群中的发布与订阅Distributed Publish Subscribe in Cluster 简单实现示 ...
- 25个led灯新玩法
Microbit板子的25个led灯,是5X5的阵列,led(lights emitting diodes)中文叫发光二极管,有单向导电性,还发光,有各种颜色的,红,蓝,黄等等.mPython可以让你 ...
- 手机上的unity路径
转载自:https://www.xuanyusong.com/archives/2656 Application.dataPath路径在PC上无论是Editor还是运行时毫无压力非常万能,但是在手机上 ...
- vue日历/日程提醒/html5本地缓存
先上图 功能: 1.上拉日历折叠,展示周 2.左右滑动切换月 2.“今天”回到今天:“+”添加日程 3.localStorage存储日程 index,html <body> <div ...
- java基础 抽象
/** * 抽象方法:就是加上abstract关键字,并去掉大括号,分号结束 * 抽象类:抽象方法坐在的类,必须是抽象类.在class前家abstract即可 * * 如何使用抽象类和抽象方法: * ...
- C# MemcacheHelper封装
using Memcached.ClientLibrary; using System; using System.Collections.Generic; using System.Linq; us ...
- Java自学-数字与字符串 字符
Java中的字符 示例 1 : 保存一个字符的时候使用char package character; public class TestChar { public static void main(S ...
- Windows Server2008服务器ping不通问题解决
https://blog.csdn.net/x541211190/article/details/78221949