【题解】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); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530239.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(19)  评论(1编辑  收藏  举报  
点击右上角即可分享
微信分享提示