【题解】ABC210 E - Distance on Large Perfect Binary Tree

我考后整整写了 1 个多小时 …

sol:
考验强大的数学推演能力

我们把一个节点视作 01 序列,走左子树相当于在序列末尾添加 0 ,走右子树相当于添加 1 。

那么两个点的距离其实取决于公共前缀的长度。

所以我们想到枚举 lca ,同时根据完全二叉树的对称性可知相同深度的点对答案的贡献是一样的。

首先枚举 i = 0 ~ n-1 表示深度。

这里必须分两种情况计算:

  1. 两个点在同一子树内, 2 i ∗ 2 m = 2 i + m 2^{i} * 2^{m}=2^{i+m} 2i2m=2i+m
  2. 两个节点一个在左子树,一个在右子树,不难发现总数恒为 2 m − 2 2^{m-2} 2m2

假设左子树深度为 i+k ,右子树深度为 i+(m-k) ,这里 1<=k<=m-1 。因为深度不能超过 n ,所以 i+k<=n 且 i+(m-k)<=n

解出 k 的范围即可 (利用数学表达式推式子)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int Maxn=3e6+5;
const int mod=998244353;
int n,m;
ll res,f[Maxn];
int main() {
	f[0]=1;
	for(int i=1;i<=3e6;i++) {
		f[i]=f[i-1]*2%mod;
	}
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++) {
	    if(i+m<=n-1) {
	    	res=(res+f[i+m])%mod;
		}
		if(m==1) continue;
		int l=max(1,i+m-n+1),r=min(m-1,n-1-i);
		if(l<=r) {
			res=(res+(r-l+1)*f[i+m-2]%mod)%mod;
		}
	}
	printf("%lld",(res*2)%mod);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值