[NOIP模拟赛]约会date LCA(顺便填坑)
来源:互联网 发布:淘宝云客服招聘 编辑:程序博客网 时间:2024/05/21 22:55
这道题也算是厉害了,改了整整俩小时最后发现是深信的LCA打错了,悲伤啊!信仰崩塌了!
顺便复习LCA,给出模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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];
}
这道题的题解是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#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;
}
阅读全文
0 0
- [NOIP模拟赛]约会date LCA(顺便填坑)
- 【NOIP 模拟题】[T3] 约会(lca)
- [NOIP模拟][LCA]一样远
- LCA 约会
- NOIP2017模拟赛(二)~(四)填坑计划
- 补:LCYZ NOIP模拟赛T3代码 : 倍增LCA || LCT动态树[虽然NOIP知识但还是五星QAQ]
- #NOIP模拟赛#单向道路(LCA or 子树和-> 边的贡献)
- noip模拟赛公交车(这也留一个坑)
- 福尔摩斯的约会(模拟)
- 约会 倍增lca
- [noip模拟赛]祖先(dp)
- [noip模拟赛]旅行Pod(spfa)
- [noip模拟赛]二进制(dp)
- [noip模拟赛]求和(快速幂)
- [noip模拟赛]中位数(乱搞)
- [noip模拟赛]邮递员送信(spfa)
- [noip模拟赛]敲砖块(dp)
- noip模拟赛(一)魔法树
- linux中history命令的简单使用
- 表单属性与方法
- 金蝶K3 SQL报表系列-BOM成本汇总表
- JS中typeof用法
- maven的生命周期
- [NOIP模拟赛]约会date LCA(顺便填坑)
- 用java打印空心菱形
- 对数几率回归
- (没有用的)为什么要注册CSDN博客
- DI之循环依赖
- HDU 2018 母牛的故事
- Python查找一个文章里出现次数最多的10的单词
- A1025. PAT Ranking (25)
- STM32的RS485调试过程记录