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)很明显可以用所有点对减去不合法点对
∑n−1i=0i(k2n−i−1−ki)k−1
,通过若干步复杂的简化过后,它就成为了
k2n−k−(2n−1)kn(k−1)
(不要问我怎么弄出来的,要用到等比数列公式),次幂直接快速幂解决就行了。
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.