算法 0:
猜测答案关于
n 是一个常系数线性递推数列,暴力算出前若干项后,使用 Berlekamp-Massey 之类的算法求解出递推式,即可以
Θ(logn) 的时间复杂度计算一组数据。
算法 1:
考虑枚举转向的次数
m,并枚举在
m+1 个方向上移动的步数
a0,⋯,am,其中
a0 可以为
0,其它都
必须是正整数。为了形式上简洁,这点不会在接下来的式子中写明。
看到「转向」这个操作,又是在平面上运动,那我们自然地想到用复数来刻画。设
ω 为
12 阶
1 次单位根(即
exp(6πi)),则答案为
∑m=0npm(1−p)n−m∑a0+⋯+am=n∑j=0maj(ωj)2
而我们知道共轭复数的性质
∣z∣2=zzˉ,所以内层和式可以表示为
∑a0+⋯+am=n∑j=0m∑k=0majakωjω−k=∑j=0m∑k=0mωj−k∑a0+⋯+am=najak
再将
∑ajak 的值关于
j,k 做分类讨论:
-
j=k=0 时:
[xn](1−x)3x(1+x)(1−xx)m
-
j,k 中有一个为零,另一个不为零:
[xn]((1−x)2x)2(1−xx)m−1
-
j=k=0 的情况有
m 种:
[xn](1−x)3x(1+x)(1−xx)m−11−x1
-
j=k,且均不为零的情况:
[xn]((1−x)2x)2(1−xx)m−21−x1
合并起来稍微化简一下,设
fm=∑j=1mωj=1−ωω−ωm+1
答案就可以表示为
[xn]∑m=0∞pm(1−p)n−m(1−xx)m(1−x)31(x(1+x)+x(fm+fˉm)+mx+fmfˉm)
等比数列求和可以得到一个关于
x 的有理分式,然后用你喜欢的线性递推算法提取其
[xn] 系数即可。