【链接】 我是链接,点我呀:)

【题意】

在这里输入题意

【题解】

最近公共祖先。
(树上倍增

一开始统计出每个子树的节点个数_size[i]

如果x和y相同。

那么直接输出n.

否则求出x和y的最近公共祖先。z

(假定y的深度大于x

【1】如果z等于x或y中的一个。

那么久就找到x..y的路径(长度设为L)中的中点u。

显然,u和它的其他len-1个子树上的任意一个节点都是可行的(除了那个包含y的子树

设_get(x,step)表示x节点往上走step步到达的节点

则输出_sum[中点]-_sum[ _get(y,L/2) ]即可

【2】如果z不等于x和y中的任意一个。

①x和y往上走的距离是一样的。

->那么z的子树中,除了这两个节点往上走上来的子树,

其他子树里面的节点都是可行的

②x和y往上走的距离不一样。

->那么就还是和【1】中的情况一样,找出中点即可。

_get(x,step)函数可以用树上倍增的p数组实现。

【代码】

#include <bits/stdc++.h>
using namespace std; const int MAXN = 1e5+10;
const int MAX = 17; vector <int> son[MAXN],g[MAXN];
int n,p[MAXN][MAX+5],dep[MAXN],pre[MAX+5],m;
int _size[MAXN]; void dfs(int x,int f)
{
_size[x] = 1;
dep[x] = dep[f] + 1;
p[x][0] = f;
for (int i = 1; i <= MAX; i++) p[x][i] = p[p[x][i - 1]][i - 1];
int len = g[x].size();
for (int i = 0; i <= len - 1; i++)
{
int y = g[x][i];
if (y != f) {
son[x].push_back(y);
dfs(y, x);
_size[x]+=_size[y];
}
}
} int _get(int x,int ma){
for (int i = MAX;i>=0;i--){
if (ma>=pre[i]){
ma-=pre[i];
x = p[x][i];
}
}
return x;
} int main()
{
ios::sync_with_stdio(0),cin.tie(0);
#ifdef LOCAL_DEFINE
freopen("rush.txt","r",stdin);
#endif
pre[0] = 1;
for (int i = 1; i <= MAX; i++)
pre[i] = pre[i - 1] << 1;
cin >> n;
for (int i = 1; i <= n; i++)
son[i].clear();
for (int i = 1; i <= n - 1; i++)
{
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1, 0);
cin >> m;
for (int i = 1; i <= m; i++)
{
int t0, t1,pret1,pret0;
cin >> t0 >> t1;
if(t0==t1){
cout<<n<<endl;
continue;
}
if (dep[t0] > dep[t1]) swap(t0, t1);
pret1 = t1;
pret0 = t0;
int dist0 = 0,dist1 = 0;
for (int i = MAX; i >= 0; i--)
if (dep[t0] <= dep[t1] - pre[i]){
t1 = p[t1][i];
dist1 += pre[i];
}
//t1��t0����ͬһ�߶�
if (t1 == t0)
{
if ((dist0+dist1)%2==0){
int dis = (dist0+dist1)/2;
int special = _get(pret1,dis);
cout << _size[special] - _size[_get(pret1,dis-1)]<<endl;
}else{
cout<<0<<endl;
}
continue;
}
for (int i = MAX; i >= 0; i--)
{
if (p[t0][i] == p[t1][i]) continue;
dist0+=pre[i];dist1+=pre[i];
t0 = p[t0][i], t1 = p[t1][i];
}
dist0+=pre[0],dist1+=pre[0];
t0 = p[t0][0];
if (dist0==dist1){
cout << _size[1]-_size[_get(pret0,dist0-1)]-_size[_get(pret1,dist1-1)] << endl;
}else{
if ((dist0+dist1)%2==0){
int dis = (dist0+dist1)/2;
int special = _get(pret1,dis);
cout << _size[special] - _size[_get(pret1,dis-1)]<<endl;
}else{
cout<<0<<endl;
}
}
} return 0;
}

【Henu ACM Round#15 E】 A and B and Lecture Rooms的更多相关文章

  1. 【Henu ACM Round#15 F】Arthur and Questions

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] a1+a2+...+ak<a2+a3+...ak+1 ->a1<ak+1 a2+a3+...+ak+1<a3 ...

  2. 【Henu ACM Round#15 D】Ilya and Escalator

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 概率DP; 设f[i][j]表示前i个单位时间,j个人进入房间的概率是多少 然后想一下和i-1秒的时候要怎么转移就可以了. i-1秒 ...

  3. 【Henu ACM Round#15 C】 A and B and Team Training

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举第一种方法. 剩下的全都个第二种方法. 看看能组成多少个队伍就可以了. [代码] #include <bits/stdc+ ...

  4. 【Henu ACM Round#15 B】A and B and Compilation Errors

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 开3个map, 存在map里面: 然后迭代第一个和第二个map; 分别与第二个和第三个map比较就可以了 [代码] #include ...

  5. 【Henu ACM Round#15 A】 A and B and Chess

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 统计大写和小写的个数. 比较答案.输出即可. [代码] #include <bits/stdc++.h> using n ...

  6. 【Henu ACM Round#16 A】 Bear and Game

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 看看什么时候t[i]-t[i-1]>15. 输出t[i-1]+15就好. 不存在这样的i就输出min(t[n]+15,90) ...

  7. 【Henu ACM Round#24 E】Connected Components

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 要求把连续的一段li..ri的边全都删掉. 然后求剩下的图的联通数 如果暴力的话 复杂度显然是O(k*m)级别的. 考虑我们把li. ...

  8. 【Henu ACM Round#24 D】Iterated Linear Function

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把B提取出来就是一个等比数列了. 求和一下会发现是这种形式. \(B*\frac{(A^n-1)}{A-1}+A^n*x\) 则求一 ...

  9. 【Henu ACM Round#24 C】Quiz

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 肯定是这样 先放k-1个,然后空1个,然后再放k-1个.然后再空1个.. 以此类推. 然后如果(n/k)*(k-1)+n%k> ...

随机推荐

  1. 使用具体解释及源代码解析Android中的Adapter、BaseAdapter、ArrayAdapter、SimpleAdapter和SimpleCursorAdapter

    Adapter相当于一个数据源,能够给AdapterView提供数据.并依据数据创建相应的UI.能够通过调用AdapterView的setAdapter方法使得AdapterView将Adapter作 ...

  2. Gcc/MinGW/Cygwin/Msys 分别是什么?

    一.GCC的历史 GCC是一个原本用于Unix-like系统下编程的编译器. 不过,现在GCC也有了许多Win32下的移植版本. 所以,也许对于许多Windows开发者来说,GCC还是一个比较陌生的东 ...

  3. 35.自己实现vector模板库myvector

    myvector.h #pragma once //自己写的vector模板库 template <class T> class myvector { public: //构造 myvec ...

  4. Andoid 更好的Android多线程下载框架

    概述 为什么是更好的Android多线程下载框架呢,原因你懂的,广告法嘛! 本篇我们我们就来聊聊多线程下载框架,先聊聊我们框架的特点: 多线程 多任务 断点续传 支持大文件 可以自定义下载数据库 高度 ...

  5. 让IE9以下版本的浏览支持html5,CSS3的插件

    随着html5(后面用h5代表)标签越来越广泛的使用,IE9以下(IE6-IE8)不识别h5标签的问题让人很是烦恼. 在火狐和chrome之类的浏览器中,遇到不认识的标签,只要给个display:bl ...

  6. 实现echarts内外圈联动

    //控制都是通过控制series中data的name,那么将内外圈需要同事控制的部分设置为一样的名字,就可以实现内外圈联动. //但是在name相同时,会使默认分配颜色时相同,使颜色不好看,这里就需要 ...

  7. Design Doc: Session History for Out-of-Process iframes

    Design Doc: Session History for Out-of-Process iframes Charlie Reis, May 2014 This document outlines ...

  8. NodeJS学习笔记 进阶 (13)Nodejs进阶:5分钟入门非对称加密用法

    个人总结:读完这篇文章需要5分钟,这篇文章讲解了Node.js非对称加密算法的实现. 摘录自网络 地址: https://github.com/chyingp/nodejs-learning-guid ...

  9. 学习Go语言之使用channel避免竞态问题

    // 使用channel避免竞态问题 package main import ( "fmt" "sync" ) var ( i int wg sync.Wait ...

  10. 学习《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码

    入门神经网络深度学习,推荐学习<深度学习入门:基于Python的理论与实现>,这本书不来虚的,一上来就是手把手教你一步步搭建出一个神经网络,还能把每一步的出处讲明白.理解神经网络,很容易就 ...