【NOIP提高组】最近公共祖先

20 篇文章 0 订阅
5 篇文章 0 订阅

Description

YJC最近在学习树的有关知识。今天,他遇到了这么一个概念:最近公共祖先。对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。YJC很聪明,他很快就学会了如何求最近公共祖先。他现在想寻找最近公共祖先有什么性质,于是他提出了这样的一个问题:n层的满k叉树T,求对于每一对(i,j)(1≤i,j≤T的点数),LCA(T,i,j)的深度的和是多少。这个数字n层的满k叉树指一棵带标号的有根树,深度为i(0≤i

Solution

比赛的时候其实没有想到一个比较好的递推式,自己推了个诡异的递推式,但是发现当答案小于模数时是对的,超过了模了之后就错掉了。
正解其实吼简单,优化O(n)的式子。O(n)很明显可以用所有点对减去不合法点对 n1i=0i(k2ni1ki)k1 ,通过若干步复杂的简化过后,它就成为了 k2nk(2n1)kn(k1) (不要问我怎么弄出来的,要用到等比数列公式),次幂直接快速幂解决就行了。

Code

const mo=998244353;
var
    n:longint;
    k,ans,ni:int64;
function ksm(x,y:int64):int64;
begin
    if y=0 then exit(1);
    if y mod 2=1 then ksm:=x*ksm(x,y-1) mod mo else ksm:=sqr(ksm(x,y div 2)) mod mo;
    exit(ksm);
end;
begin
    readln(n,k);
    ni:=(k-1)*(k-1) mod mo*(k-1) mod mo;
    ni:=ksm(ni,mo-2);
    ans:=ksm(k,2*n)-k;
    ans:=(ans-((2*n-1)*ksm(k,n))mod mo*(k-1))mod mo;
    ans:=ans*ni mod mo;
    while ans<0 do ans:=ans+mo;
    writeln(ans);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值