CodeForces 519E A and B and Lecture Rooms(倍增)
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 - 1corridors 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.
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.
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.
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 题意:给出一棵树,m组询问,询问与点u和点v距离相等的点的个数 题解:首先最容易胡出来的是如果一个点到u和v的距离相等,他们肯定是u到v路径上中点的非u、v链以外的全部子树大小之和
然后考虑倍增计算u到v的距离,显然中心会在深度较大的那个点到u与vlca的路径上,高度为距离除二
很明显,如果距离为奇数就无解,为偶数则可以从较低的点直接倍增跳上去,得到这个中点的子树中含点u的那个,直接减去
至于含点v的肯定是父节点那条,不予考虑
因为上面的前提是两点深度不等,所以深度相等的时候要特判,显然u和v都要倍增往上跳,不存在一条路径来自其父亲
然后两点相等最好也特判一下,大概就能A了 代码如下:
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cctype>
#include<string>
#include<sstream>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; int n,m,fa[][],deep[],size[];
vector<int> g[]; void dfs(int now,int f,int dep)
{
deep[now]=dep;
fa[][now]=f;
size[now]=;
for(int i=;i<=;i++)
{
fa[i][now]=fa[i-][fa[i-][now]];
}
for(int i=;i<g[now].size();i++)
{
if(g[now][i]==f) continue;
dfs(g[now][i],now,dep+);
size[now]+=size[g[now][i]];
}
} int get(int u,int v)
{
if(u==v) return n;
if(deep[u]==deep[v])
{
for(int i=;i>=;i--)
{
if(fa[i][u]!=fa[i][v])
{
u=fa[i][u];
v=fa[i][v];
}
}
return n-size[u]-size[v];
}
if(deep[u]<deep[v]) swap(u,v);
int x=u,y=v,dis1=,dis2=;
for(int i=;i>=;i--)
{
if(deep[fa[i][x]]>=deep[y])
{
x=fa[i][x];
dis1+=pow(,i);
}
}
if(x==y)
{
if(dis1%==) return ;
int need=dis1/;
need--;
for(int i=;i>=;i--)
{
if(need&(<<i))
{
u=fa[i][u];
}
}
return size[fa[][u]]-size[u];
}
else
{
for(int i=;i>=;i--)
{
if(fa[i][x]!=fa[i][y])
{
x=fa[i][x];
dis1+=pow(,i);
y=fa[i][y];
dis2+=pow(,i);
}
}
if((dis1+dis2+)%==) return ;
int need=(dis1+dis2+)/;
need--;
for(int i=;i>=;i--)
{
if(need&(<<i))
{
u=fa[i][u];
}
}
// printf("nowu:%d\n",u);
return size[fa[][u]]-size[u];
}
} int main()
{
scanf("%d",&n);
int from,to;
for(int i=;i<=n-;i++)
{
scanf("%d%d",&from,&to);
g[from].push_back(to);
g[to].push_back(from);
}
dfs(,,);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&from,&to);
printf("%d\n",get(from,to));
}
}
CodeForces 519E A and B and Lecture Rooms(倍增)的更多相关文章
- Codeforces 519E A and B and Lecture Rooms [倍增法LCA]
题意: 给你一棵有n个节点的树,给你m次询问,查询给两个点,问树上有多少个点到这两个点的距离是相等的.树上所有边的边权是1. 思路: 很容易想到通过记录dep和找到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 519E A and B and Lecture Rooms
http://codeforces.com/contest/519/problem/E 题意: 给出一棵树和m次询问,每次询问给出两个点,求出到这两个点距离相等的点的个数. 思路: lca...然后直 ...
- 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]E. A and B and Lecture Rooms(树上倍增)
题目:http://codeforces.com/problemset/problem/519/E 题意:给你一个n个点的树,有m个询问(x,y),对于每个询问回答树上有多少个点和x,y点的距离相等 ...
- CodeForces 519E 树形DP A and B and Lecture Rooms
给出一棵树,有若干次询问,每次询问距两个点u, v距离相等的点的个数. 情况还挺多的,少侠不妨去看官方题解.^_^ #include <iostream> #include <cst ...
- Codeforces 519 E. A and B and Lecture Rooms
Description 询问一个树上与两点距离相等的点的个数. Sol 倍增求LCA. 一棵树上距离两点相等,要么就只有两点的中点,要么就是与中点相连的所有点. 有些结论很容易证明,如果距离是偶数,那 ...
随机推荐
- python 3389爆破机
前言: = =上学后的第一个星期假期,写了个3389爆破器 - 0x01 准备: hydra 钟馗之眼API 0x02代码: import optparse import os import requ ...
- 【C++】
C++声明function后面加上等于0(=0)何解? https://zhidao.baidu.com/question/1446181256925153340.html
- Tkinter Menubutton(菜单按钮)
Python - Tkinter Menubutton: 一个菜单按钮是一个下拉菜单,在屏幕上停留时间的一部分.菜单的小工具,可以显示该菜单按钮的选择,当用户点击它与每个menubutton时. ...
- hadoop性能测试
一.hadoop自带的性能基准评测工具 (一)TestDFSIO 1.测试写性能 (1)若有必要,先删除历史数据 $hadoop jar /home/hadoop/hadoop/share/hadoo ...
- Rhel5.5配置Centos yum源
ruiy哥,抛砖引玉 当你使用rhel系统时,[大部分数据库中心及政府企业选择linux服务器时通常考虑采购的版本一般不外乎是Rhel红帽及Suse,理由你懂的EcoSystem!]你没有一个红帽网络 ...
- 使用C#书写SQLite数据库增删改查语句(以及插入byte[]时遇到的问题总结)
在没有使用SQLite这种轻量级的数据库之前,只使用过Sqlserver2008进行数据的增删改查,公司使用的是大型的ORACLE数据库,还没有真正的会使用它.那时候觉得数据库很庞大,然而遇到SQLi ...
- Yum -y update 报错
问题描述: 操作系统:CentOS 6.5 今天服务器上执行 yum -y update 命令时,提示: Running rpm_check_debug ERROR with rpm_check_de ...
- Elasticsearch学习系列之term和match查询实例
Elasticsearch查询模式 一种是像传递URL参数一样去传递查询语句,被称为简单查询 GET /library/books/_search //查询index为library,type为boo ...
- Perl 变量:哈希变量
Perl 哈希变量哈希是 key/value 对的集合.Perl中哈希变量以百分号 (%) 标记开始.访问哈希元素格式:${key}. 1.创建哈希创建哈希可以通过以下两种方式: 1.为每个 key ...
- Java核心技术-Java的基本程序设计结构
1.一个简单的Java应用程序 public class FirstSample { public static void main(String[] args) { System.out.pring ...