【LCA】洛谷P6374 「StOI-1」树上询问

???????!数组无脑开大——就过了???!!!震惊,它卡了我半天诶??!wtm瞳孔地震。

Link


题目


Sample input #1
10 5
1 2
1 3
2 4
2 5
2 10
5 6
3 7
7 8
7 9
4 6 2
4 10 1
6 8 3
9 10 2
4 10 5
Sample output #1
7
0
1
4
0

Sample input #2
10 5
1 2
1 3
2 4
2 5
2 10
5 6
3 7
7 8
7 9
4 6 2
4 10 1
6 8 3
9 10 2
4 10 5
Sample output #2
7
0
1
4
0

Sample input #3
20 10
1 2
1 3
1 4
2 5
2 6
3 10
4 13
4 14
6 7
6 8
10 11
4 15
4 16
8 9
11 12
16 17
16 18
16 19
17 20
15 19 16
1 12 1
20 20 20
7 7 8
1 8 3
5 20 2
2 9 6
9 12 1
9 12 2
9 12 3
Sample output #3
4
16
20
0
0
5
2
10
2
1

先立一个根:x,y的lca为k
对于这么一个图我们可以发现:

  1. z只有在x到y的最短路上才可能成为x,y的lca。即z在(x 到 k)上或 (y到k)上;
  2. 对于x到y的最短路上的点除了z点外的点都不能取,包括这些不能取的点的子节点;

看到这里,答案显而易见:
*z在x到y的最短路上时:减去z的含有x或y的子树后,剩余的点数量
*z不在x到y的最短路上时:0

关于剩余的点数量:我们可以先求出Zi[i]代表当1为根时,i点的子树大小。最后计算时用倍增跑一下,得到要删的子树的根即可。


Code

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,s,t,ans,cnt;
int l[7000005],jump[7000005],Deep[7000005],father[7000005][31],Zi[7000005],tim[700005];
struct asdf{
   
 int to,next;
} A[50000010];
void read(){
   
 int x,y;
 scanf("%d%d",&n,&m);
 for(int i = 1; i < n; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值