原题链接
参考资料
解题思路
定义点阵的大小为正三角形底边点的个数,即边长 +1。
令 an 表示大小为 n 的点阵包含的总点数,可以通过组合公式得出:
an=2n(n+1)
在大小为 k 的点阵中,任意选取 3 个点的总方案数为 Cak3。
如图所示,考虑大小为 i 的正三角形框(图中为 i=7):
在这种大小为 i 的三角形框中,三边对应位置的任意三个点可以构成一个正三角形。因此,每个大小为 i 的三角形框包含 i−1 个正三角形。
对于大小为 i 的三角形框,其顶点可以位于大小为 k−i+1 的点阵中,这样的点阵包含 ak−i+1 个顶点。因此,每个大小为 i 的三角形框总共有 ak−i+1 个位置可以被选取。
因此:
Pk=Cak3∑i=1k(i−1)ak−i+1=2k(k+1)(2k(k+1)−1)(2k(k+1)−2)⋅61∑i=1k(i−1)(k−i+1)(k−i+2)⋅21=k(k+1)(k(k+1)−2)(k(k+1)−4)24∑i=1k(i−1)(k−i+1)(k−i+2)=k(k+1)(k2+k−2)(k2+k−4)24(−k3−3k2−2k+∑i=1ki3−(2k+4)∑i=1ki2+(k2+5k+5)∑i=1ki=(k4+2k3−k2−2k)(k2+k−4)2(k4+2k3−k2−2k)=k2+k−42
令 r1,r2 为 k2+k−4 的两个根:
r1=2−1+17,r2=2−1−17
则:
k=m∑∞Pk=k=m∑∞k2+k−42=k=m∑∞(k−r1)(k−r2)2=172k=m∑∞(k−r11−k−r21)=172n→∞lim(k=m∑nk−r11−k=m∑nk−r21)=172n→∞lim((ψ(n−r1+1)−ψ(m−r1))−(ψ(n−r2+1)−ψ(m−r2)))=172(ψ(m−r2)−ψ(m−r1)+n→∞lim(ψ(n−r1+1)−ψ(n−r2+1)))=172(ψ(m−r2)−ψ(m−r1)+n→∞lim((ψ(1)+k=1∑n−r1k1)−(ψ(1)+k=1∑n−r2k1)))=172(ψ(m−r2)−ψ(m−r1)+n→∞limk=n−r2+1∑n−r1k1)=172(ψ(m−r2)−ψ(m−r1)+0)=172(ψ(m−2−1−17)−ψ(m−2−1+17))=172(ψ(m+21+17)−ψ(m+21−17))
其中 ψ(x) 是 Digamma 函数,其定义为:
ψ(x)=dxdlnΓ(x)=Γ(x)Γ′(x)
Digamma 函数满足以下递推关系:
ψ(x+1)=ψ(x)+x1
ψ(x) 也可以用伯努利数 B2k 表示为:
ψ(x)=ln(x)−2x1−k=1∑∞2k⋅x2kB2k
当 x≫1 时,Digamma 函数可以用渐近展开式近似为:
ψ(x)=ln(x)−2x1−12x21+120x41+o(x−4)
在 x 较小时,可以通过递推关系放大。用渐进展开式求近似值。
参考代码
#include <bits/stdc++.h>
using namespace std;
double digamma(double x)
{
double res=0;
while(x<10){res-=1/x;x++;}
res+=log(x)-1/(x*2)-1/(x*x*12)+1/(x*x*x*x*120);
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int m;
cin>>m;
if(m==1)
{
cout<<"1.7984x10^0"<<'\n';
return 0;
}
double r1=(1.0-sqrt(17))/2,r2=(1.0+sqrt(17))/2;
double ans=(digamma(m+r1)-digamma(m+r2))*(-2)/sqrt(17);
int cnt=0;
while(ans<1){cnt--;ans*=10;}
cout<<fixed<<setprecision(4)<<ans<<"x10^"<<cnt<<'\n';
return 0;
}