记 (f_i) 代表 (i) 个轮状病毒且头尾没有连在一起的方案数,(g_i) 代表头尾连在一起了的方案数。
有 (f_i=sumlimits_{j=1}^{i}f_{i-j} imes j,g_i=sumlimits_{j=1}^if_{i-j} imes j imes (j-1))。
我们发现这样做是 (O(n^2))(理论上 (n^3) 的矩阵树定理也能过),考虑优化到 (O(n))
我们可以使用差分来解决。
[Delta f_i=sum_{j=1}^{i}f_{i-j} imes j-sumlimits_{j=1}^{i-1}f_{i-1-j} imes j=sumlimits_{j=0}^{i-1}f_j imes (i-j)-sumlimits_{j=0}^{i-2}f_{j} imes (i-1-j)
]
[Rightarrow Delta f_i=sumlimits_{j=0}^{i-1}f_j
]
那么我们同时维护 (f_i) 的前缀和即可推出 (f_i)。
我们对 (g_i) 同样做差分:
[Delta g_i=sum_{j=1}^{i}f_{i-j} imes j imes (j-1)-sumlimits_{j=1}^{i-1}f_{i-1-j} imes j imes (j-1)=sumlimits_{j=1}^{i-1}f_{i-1-j} imes j imes 2=f_{i-1} imes 2
]
这样求出 (f) 后也可以求 (g) 了,最后的答案即为 (f_n+g_n)。
因为这题答案会炸int128所以还要写高精度,这里给一份py的代码:
a=[]
b=[]
c=[]
n=int(input())
a.append(1)
a.append(1)
b.append(1)
b.append(2)
c.append(0)
c.append(0)
for i in range(2,n+1):
a.append(a[i-1]+b[i-1])
b.append(b[i-1]+a[i])
c.append(c[i-1]+2*a[i-16])
print(a[n]+c[n])