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

【题意】

在这里输入题意

【题解】

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

一开始统计出每个子树的节点个数_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. Codeforces Round #271 (Div. 2) 解题报告

    题目地址:http://codeforces.com/contest/474 A题:Keyboard 模拟水题. 代码例如以下: #include <iostream> #include ...

  2. js面向对象编程:怎样定义常量?

    js中有一个keywordconst,但眼下的浏览器似乎还不支持,假设一定要定义一些常量,事实上能够使用闭包,匿名函数实现常量的定义. 比如: var Class = (function() { va ...

  3. android openGL ES2 一切从绘制纹理開始

    纹理.在openGL中,能够理解为载入到显卡显存中的图片.Android设备在2.2開始支持openGL ES2.0.从前都是ES1.0 和 ES1.1的版本号.简单来说,openGL ES是为了嵌入 ...

  4. JavaScript总结(2)

    <!--脚本部分-->06 <script type="text/javascript">07 date_object=new Date();08 what ...

  5. 51Nod 最长的循环节(打表预处理)

    正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数.     1/6= ...

  6. windows gitbub使用

    1.安装git bush (windows没什么好说的 下一步,下一步,,) 2. 通过gitbush命令行生成密钥: (拷贝密钥) 3.密钥添加到github上面: 4.克隆项目: 5.提交: 查看 ...

  7. python实例

    先来一段代码: #这段代码可牛逼了,1.可以根据indent的选项调整模式.2.根据level调整级别. #代码很low,主要看思想..哈哈哈..看看从最初的样子到最好经历了什么.. 开始: #!/u ...

  8. PHP7内核剖析之执行流程

    以fpm为例: 1.fpm启动时,会先执行 module_startup, 并随着fpm进程常驻 2.当一个请求到达之后,会执行 request_startup, 进行一些请求初始化工作,然后执行代码 ...

  9. bzoj1612 Usaco08 Jan 牛大赛

    水题模拟 建一个图,每两个牛进行比赛就连一条边,然后两遍dfs求出比他弱和比他强的牛,最后如果相加数量等于n,说明他能与全部的牛进行比较,排名确定. #include<bits/stdc++.h ...

  10. C#-修改图书借阅管理系统-错误与SQL server 2008错误、复制数据库

    VS2012错误: *)不存在从对象类型 System.Object[] 到已知的托管提供程序本机类型的映射 public DataTable loadData2UserSearch(params o ...