题目链接:E. A and B and Lecture Rooms

题目大意

给定一颗节点数10^5的树,有10^5个询问,每次询问树上到xi, yi这两个点距离相等的点有多少个。

题目分析

若 x==y 直接返回 n。

先求出 x, y 两个点的中点。

先求出 LCA(x, y) = z,假设 Depth[x] >= Depth[y] ,若Depth[x] == Depth[y] ,那么 z 就是它们的中点。

答案就是,n - Size[fx] - Size[fy],fx 是从x向上跳,一直跳到 z 的一个孩子就停止,这个孩子就是 fx。

否则中点一定在从 x -- z -- y 的路径上 x -- z 的一段,为 Jump(x, t) ,t 是 x -- z -- y 长度的一半。如果 x -- z -- y 的长度是奇数,就返回 0。

这个 Jump(a, b) 就是用倍增来求的。

答案就是, Size[o] - Size[fx]。这里的o是中点,fx是从x向上跳,跳到o的一个孩子就停止。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std; const int MaxN = 100000 + 5, MaxLog = 19 + 5; int n, m;
int Depth[MaxN], Father[MaxN], Jump[MaxN][MaxLog], Size[MaxN]; struct Edge
{
int v;
Edge *Next;
} E[MaxN * 2], *P = E, *Point[MaxN]; inline void AddEdge(int x, int y)
{
++P; P -> v = y;
P -> Next = Point[x]; Point[x] = P;
} void DFS(int x, int Dep, int Fa)
{
Depth[x] = Dep;
Father[x] = Fa;
Size[x] = 1;
for (Edge *j = Point[x]; j; j = j -> Next)
{
if (j -> v == Father[x]) continue;
DFS(j -> v, Dep + 1, x);
Size[x] += Size[j -> v];
}
} void Prepare()
{
for (int i = 1; i <= n; ++i) Jump[i][0] = Father[i];
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= 18; ++j)
Jump[i][j] = Jump[Jump[i][j - 1]][j - 1];
} int JumpUp(int x, int y)
{
int ret = x;
for (int i = 0; i <= 18; ++i)
if (y & (1 << i)) ret = Jump[ret][i];
return ret;
} int LCA(int x, int y)
{
if (Depth[x] < Depth[y]) swap(x, y);
int Dif;
Dif = Depth[x] - Depth[y];
if (Dif) x = JumpUp(x, Dif);
if (x == y) return x;
for (int i = 18; i >= 0; --i)
{
if (Jump[x][i] != Jump[y][i])
{
x = Jump[x][i];
y = Jump[y][i];
}
}
return Father[x];
} int Query(int x, int y)
{
if (x == y) return n;
if (Depth[x] < Depth[y]) swap(x, y);
int z, tx, ty, fx, fy, t, o;
z = LCA(x, y);
tx = Depth[x] - Depth[z];
ty = Depth[y] - Depth[z];
t = tx + ty;
if (t & 1) return 0;
if (Depth[x] == Depth[y])
{
fx = JumpUp(x, tx - 1);
fy = JumpUp(y, ty - 1);
return n - Size[fx] - Size[fy];
}
else
{
t >>= 1;
o = JumpUp(x, t);
fx = JumpUp(x, t - 1);
return Size[o] - Size[fx];
}
} int main()
{
scanf("%d", &n);
int a, b;
for (int i = 1; i <= n - 1; ++i)
{
scanf("%d%d", &a, &b);
AddEdge(a, b);
AddEdge(b, a);
}
scanf("%d", &m);
DFS(1, 0, 0);
Prepare();
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &a, &b);
printf("%d\n", Query(a, b));
}
return 0;
}

  

[CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】的更多相关文章

  1. [CF Round #294 div2] D. A and B and Interesting Substrings 【Map】

    题目链接:D. A and B and Interesting Substrings 题目大意 给定26个小写字母的权值,一共26个整数(有正有负). 给定一个小写字母组成的字符串(长度10^5),求 ...

  2. 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 ...

  3. CF Round #580(div2)题解报告

    CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...

  4. CF round #622 (div2)

    CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...

  5. [CF Round #295 div2] C. DNA Alignment 【观察与思考0.0】

    题目链接:C. DNA Alignment 题目大意就不写了,因为叙述会比较麻烦..还是直接看英文题面吧. 题目分析 经过观察与思考,可以发现,构造的串 T 的每一个字符都与给定串 S 的每一个字符匹 ...

  6. A. Grasshopper And the String(CF ROUND 378 DIV2)

    A. Grasshopper And the String time limit per test 1 second memory limit per test 256 megabytes input ...

  7. A. Alyona and Numbers(CF ROUND 358 DIV2)

    A. Alyona and Numbers time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. CF Round#436 div2

    额,这次的题目其实挺智障的.所以通过这次比赛,我也发现了自己是一个智障.... 不说太多,说多是泪... A. Fair Game 题意:给你一个数组,看你能否把它均分为两个所有元素均相同的子数组. ...

  9. CF Round #569 Div2(contest1180)

    比赛链接:http://codeforces.com/contest/1180 Problem A 题意:给出n,问方块数.看图理解... Solution: 找一找规律就可以了,发现方块数为2n*( ...

随机推荐

  1. Activiti5.13数据库表结构设计

    1.结构设计 1.1.    逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...

  2. cf 85 E. Petya and Spiders

    http://codeforces.com/contest/112/problem/E 轮廓线dp.每一个格子中的蜘蛛选一个去向.终于,使每一个蜘蛛都有一个去向,同一时候保证有蜘蛛的格子最少.须要用4 ...

  3. activity-intent-startActivity-startActivityResult

    一. Intent和startActivity 1.在一个Activtiy中可以使用startActivity()去开始另一个制定的Activity 但在android3.0(是针对平板出的产品)之后 ...

  4. group by是什么意思 mysql中

    mysql语法中group by是什么意思? 在百度中搜索半天,最后找到一篇解释比较好的(不是博文,是百度知道,很郁闷那么多网友怎么就没人解释的清楚),链接如下: http://zhidao.baid ...

  5. http 与https 安全链接

    安全连接 Web应用最常见的用途之一是电子商务,可以利用Web服务器端程序使人们能够网络购物,需要指出一点是,缺省情况下,通过Internet发送信息是不安全的,如果某人碰巧截获了你发给朋友的一则消息 ...

  6. 2016 11 9遇到问题 http请求的各种方式

    遇到问题:对接网易七鱼 调用他们接口是出现问题 1.对方要求  除上传文件外,其他所有接口请求Content-Type类型为:application/json;charset=utf-8:请求内容需要 ...

  7. InnoDB MyISAM区别及优化(摘录)

    InnoDB 是 MySQL 上第一个提供外键约束的引擎,除了提供事务处理外,InnoDB 还支持行锁,提供和 Oracle 一样的一致性的不加锁读取,能增加并发读的用户数量并提高性能,不会增加锁的数 ...

  8. Silverlight OOB 程序自动更新

    Silverlight OOB 程序 提供了非常方便的自动更新功能! 要让 Silverlight OOB 安装到客户端电脑后实现自动更新,必须实现以下两个条件: 一.为 程序的 xap  文件进行签 ...

  9. C#中的两种debug方法

    这篇文章主要介绍了C#中的两种debug方法介绍,本文讲解了代码用 #if DEBUG 包裹.利用宏定义两种方法,需要的朋友可以参考下   第一种:需要把调试方法改成debug代码用 #if DEBU ...

  10. grep参数说明及常用用法

    grep参数说明及常用用法 趁着午休的时间把自己经常使用的一些grep命令整理一下. 方便以后查看. 后续会逐步把awk/sed/find等常用的命令理一理. 增强下记忆. 也算是对得起自己了. ^^ ...