[NOIP模拟赛]约会date LCA(顺便填坑)

这道题也算是厉害了,改了整整俩小时最后发现是深信的LCA打错了,悲伤啊!信仰崩塌了!
顺便复习LCA,给出模板
void init(){//p[i][j]表示i节点2^j的祖先
int j;
for(j=0;(1<<j)<=n;j++)
pos(i,1,n)
p[i][j]=-1;
pos(i,1,n)
p[i][0]=fa[i];
for(j=1;(1<<j)<=n;j++)
pos(i,1,n)
if(p[i][j-1]!=-1)
p[i][j]=p[p[i][j-1]][j-1];//i的2^j祖先即为2^(j-1)祖先的2^(j-1)祖先
}
int lca(int a,int b){
int i;
if(dep[a]<dep[b]) swap(a,b);//深度深的先爬
for(i=0;(1<<i)<=dep[a];i++);
i--;
for(int j=i;j>=0;j--)
if(dep[a]-(1<<j)>=dep[b])
a=p[a][j];//爬到等高
if(a==b) return a;//如果在一条链上,直接返回
for(int j=i;j>=0;j--){
if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
a=p[a][j];b=p[b][j];//两边一起爬,直到爬到LCA
}
}
return fa[a];
}
这道题的题解是这样的:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
#define N 101000
int n,m;
struct haha{
int next,to;
}edge[N*2];
int head[N],cnt=1;
void add(int u,int v){
edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;
}
int dep[N],fa[N],size[N];
int p[N][22];
void dfs(int x){
size[x]=1;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(fa[x]!=to){
fa[to]=x;dep[to]=dep[x]+1;
dfs(to);size[x]+=size[to];
}
}
}
void init(){//p[i][j]表示i节点2^j的祖先
int j;
for(j=0;(1<<j)<=n;j++)
pos(i,1,n)
p[i][j]=-1;
pos(i,1,n)
p[i][0]=fa[i];
for(j=1;(1<<j)<=n;j++)
pos(i,1,n)
if(p[i][j-1]!=-1)
p[i][j]=p[p[i][j-1]][j-1];//i的2^j祖先即为2^(j-1)祖先的2^(j-1)祖先
}
int lca(int a,int b){
int i;
if(dep[a]<dep[b]) swap(a,b);//深度深的先爬
for(i=0;(1<<i)<=dep[a];i++);
i--;
for(int j=i;j>=0;j--)
if(dep[a]-(1<<j)>=dep[b])
a=p[a][j];//爬到等高
if(a==b) return a;//如果在一条链上,直接返回
for(int j=i;j>=0;j--){
if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
a=p[a][j];b=p[b][j];//两边一起爬,直到爬到LCA
}
}
return fa[a];
}
int get(int x,int anc,int num){
int i;
for(i=0;(1<<i)<=dep[x];i++);
i--;
for(int j=20;j>=0;j--)
if(dep[x]-(1<<j)>=dep[anc]+num)
x=p[x][j];
return x;
}
int main(){
//freopen("date.in","r",stdin);
//freopen("date.out","w",stdout);
scanf("%d",&n);
pos(i,1,n-1){
int x,y;scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(2);//cout<<fa[2];
init();
scanf("%d",&m);//system("pause");
pos(i,1,m){
int x,y;scanf("%d%d",&x,&y);
int anc=lca(x,y);
int dis=dep[x]+dep[y]-2*dep[anc];//cout<<dis<<endl;
if(dis%2==1){
printf("0\n");continue;
}
if(x==y){
printf("%d\n",n);continue;
}
if(dep[x]==dep[y]){
int p1=get(x,anc,1),p2=get(y,anc,1);
printf("%d\n",n-size[p1]-size[p2]);
continue;
}
if(dep[x]<dep[y]) swap(x,y);
int p1=get(x,x,-dis/2),p2=get(x,p1,1);
printf("%d\n",size[p1]-size[p2]);
}
return 0;
}
[NOIP模拟赛]约会date LCA(顺便填坑)的更多相关文章
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)
A.九九归一 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2355%20-%20Streaming%20%236%20(NOIP模拟赛day2)/九九归一 题 ...
- 10.16 NOIP模拟赛
目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...
- NOIP模拟赛-2018.11.7
NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...
- NOIP模拟赛-2018.11.6
NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...
- NOI.AC NOIP模拟赛 第五场 游记
NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- 2016-06-19 NOIP模拟赛
2016-06-19 NOIP模拟赛 by coolyangzc 共3道题目,时间3小时 题目名 高级打字机 不等数列 经营与开发 源文件 type.cpp/c/pas num.cpp/c ...
- NOIp模拟赛二十八
(这是NOIp模拟赛?应该是NOI模拟赛不小心加了个p) 嗯,假装这是正经的NOIp模拟赛,从今天开始也写写题解吧(这几天被虐的惨惨) 今日情况:8+50+0=58 A题输出样例,B题正解写挂,C题不 ...
随机推荐
- linux发行版和内核的关系
转自:http://m.blog.csdn.net/article/details?id=50595230 Linux内核是计算机操作系统的核心.一个完整的 Linux发行版包括了内核与一些其他与文件 ...
- 7.如何发布vue项目到服务器
1.确保程序是可运行的,即npm run dev可以运行 2.把index.js修改 3.运行npm命令npm run build 4.生成的dist文件为 直接点击index.html就能运行,部署 ...
- Unity 游戏框架搭建 (五) 简易消息机制
什么是消息机制? 23333333,让我先笑一会. 为什么用消息机制? 三个字,解!!!!耦!!!!合!!!!. 我的框架中的消息机制用例: 1.接收者 ``` using UnityEngine ...
- C/C++中对链表操作的理解&&实例分析
链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...
- Java 数据库编程 ResultSet 的 使用方法
结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...
- FineReport填报分页设置
1. 问题描述 进行FineReport数据填报时,如果数据量过大,由于前端浏览器的性能限制,如果将数据全部展现出来,速度会非常的慢,影响用户体验,这时候大家就会想,填报是否能像分页预览一样进行分页呢 ...
- Centos7yum安装Redis详细教程
原本是在自己的mac上安装redis的,通过brew去安装的redis觉得很简单,实际macos系统与centos系统还是有一些区别的. 1.yum安装redis服务 sudo yum install ...
- CentOS 6.9 升级MySQL 5.6.36到5.7.18
CentOS 6.9 升级MySQL 5.6.36到5.7.18 MySQL 5.6.36 安装过程:http://www.cnblogs.com/imweihao/p/7156754.html 升级 ...
- 《JavaScript高级程序设计》 -- 基本概念(一)
之前看过好几遍<JavaScript高级程序设计>这一书,但是始终没有完完整整的看过一遍.从现在开始我会把它完整的啃一遍,每章节都记录笔记,自己的心得,加油! 由于前三章的内容比较简单,因 ...
- Luogu 1090 合并果子(贪心,优先队列,STL运用)
Luogu 1090 合并果子(贪心,优先队列,STL运用) Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每 ...