Project Euler 378
Project Euler 378
题目
Triangle Triples
Let \(T(n)\) be the \(n^\text{th}\) triangle number, so \(T(n) = \dfrac{n(n + 1)}{2}\).
Let \(dT(n)\) be the number of divisors of \(T(n)\).
E.g.: \(T(7) = 28\) and \(dT(7) = 6\).
Let \(Tr(n)\) be the number of triples \((i, j, k)\) such that \(1 \le i \lt j \lt k \le n\) and \(dT(i) \gt dT(j) \gt dT(k)\)
\(Tr(20) = 14\), \(Tr(100) = 5772\), and \(Tr(1000) = 11174776\).
Find \(Tr(60 000 000)\).
Give the last \(18\) digits of your answer.
解决方案
令\(N=600000000\),通过线性筛预处理处理出\(1\sim N+1\)的因数个数,可以以\(O(N)\)的时间复杂度计算出所有\(dT\)值,令\(M\)是\(1\sim N\)中\(dT\)值最大的一个。
考虑使用动态规划的思想解决本题。令状态\((i,j)(1\le i\le 3,1\le j\le N)\)表示长度为\(i\)并且以\(j\)为结尾的序列有多少个(即\(p_1<p_2<\dots<p_{i-1}<j\) 并且\(dT(p_1)>dT(p_2)>\dots>dT(p_{i-1})>j\))
那么不难写出关于\(f(i,j)\)的状态转移方程:
\[ f(i,j)= \left \{\begin{aligned} &1 & & \text{if}\quad i=1 \\ &\sum_{k<j,dT(k)>j} f(i-1,k) & & \text{else} \end{aligned}\right. \]
直接进行转移的效率非常低,因此考虑使用树状数组维护状态:将当前所有\(f(i-1,k),k\le j\)的状态都按照值\(dT(k)\)存到树状数组中,那么询问时只需要以\(O(\log M)\)的时间复杂度求得大于\(dT(j)\)的所有状态之和。
最终答案为\(\sum_{j=1}^Nf(3,j)\),时间复杂度为\(O(N\log M)\)。
代码
1 |
|