题意:
三个面都是直角的三棱锥,三个棱长分别为 a , b , c a,b,c a,b,c(在 [ 1 , n ] [1,n] [1,n]中任取)。设顶点到底面的距离 h h h,求 1 h 2 \frac{1}{h^2} h21的期望。
解析:
我看官方讲解推导实在太麻烦了,于是写一下这篇博客说一下自己的推法。
既然三棱锥三个角都是直角,我们直接把顶点当作坐标原点,三条棱当作三个方向的轴,
h
h
h的求解就转换成了点到面的距离。
三维直角坐标系中点
(
x
0
,
y
0
,
z
0
)
(x_0,y_0,z_0)
(x0,y0,z0)到面
A
x
+
B
y
+
C
z
+
D
=
0
Ax+By+Cz+D=0
Ax+By+Cz+D=0的距离公式:
h
=
∣
A
x
0
+
B
y
0
+
C
z
0
+
D
∣
A
2
+
B
2
+
C
2
h=\frac{|Ax_0+By_0+Cz_0+D|}{\sqrt{A^2+B^2+C^2}}
h=A2+B2+C2∣Ax0+By0+Cz0+D∣
底面是一个过
(
0
,
0
,
a
)
,
(
b
,
0
,
0
)
,
(
0
,
c
,
0
)
(0,0,a),(b,0,0),(0,c,0)
(0,0,a),(b,0,0),(0,c,0)的面,面的公式求都不用求
a
c
x
+
a
b
y
+
b
c
z
−
a
b
c
=
0
ac\ x+ab\ y+bc\ z-abc=0
ac x+ab y+bc z−abc=0
顶点是坐标原点,直接套公式
h
=
a
b
c
a
2
b
2
+
b
2
c
2
+
a
2
c
2
h=\frac{abc}{a^2b^2+b^2c^2+a^2c^2}
h=a2b2+b2c2+a2c2abc
那么
1
h
2
=
1
a
2
+
1
b
2
+
1
c
2
\frac{1}{h^2}=\frac{1}{a^2}+\frac{1}{b^2}+\frac{1}{c^2}
h21=a21+b21+c21
a
,
b
,
c
a,b,c
a,b,c等价,
E
(
1
h
2
)
=
3
×
E
(
1
a
2
)
E(\frac{1}{h^2})=3\times E(\frac{1}{a^2})
E(h21)=3×E(a21)
线性求下逆元,再求前缀和,最后输出的时候别忘了期望还要除以概率, p r e [ n ] × i n v [ n ] % m o d pre[n]\times inv[n]\%mod pre[n]×inv[n]%mod
AC代码:
#include<cstdio>
#include <cmath>
#define pb push_back
#define fir first
#define sec second
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define sp system("pause")
#define multi int T;scanf("%d",&T);while(T--)
using namespace std;
typedef long long ll;
typedef double db;
const int N=6e6+5;
const ll mod=998244353;
const db pi=acos(-1.0);
ll inv[N],pre[N];
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void invv(int n,int p)//1~n在模p意义下逆元
{
inv[0]=inv[1]=1;
for(int i=2;i<=n;i++)
inv[i]=((-p/i*inv[p%i])%p+p)%p;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("D:\\work\\data.in","r",stdin);
#endif
invv(6e6,mod);
for(ll i=1;i<=6e6;i++){
pre[i]=(pre[i-1]+3*inv[i]*inv[i])%mod;
}
multi{
int n;
scanf("%d",&n);
printf("%lld\n",pre[n]*inv[n]%mod);
}
}