Generate three integers a, b, and c in [1,n] with equal probability independently, and use them as the three right-angle side length of a right-angled tetrahedron. Find the expectation of the reciprocal square of the distance from the right-angle apex to the slope (Euclidean distance).
For each test case, output a line containing the answer mod 998244353.
Input
In the first line, you should read an integer T denoting the number of test cases.
In every test case, the only line will include an integer n.
It is guaranteed that T is no larger than 2×106 and n is no larger than 6×106.
Output
For each test case, output the only line containing just one integer denoting the answer mod 998244353.
Sample Input
3
1
2
3
Sample Output
3
124780546
194103070
给定n,在[1,n]中等概率随机选出3个数 a , b , c a,b,c a,b,c,做直角四面体( a , b , c a,b,c a,b,c三遍两两垂直),记顶点到底面的距离为 h h h,求数学期望 E ( 1 h 2 ) E(\frac{1}{h^2}) E(h21)
设 a , b , c a,b,c a,b,c为空间直角坐标系的三条坐标轴, 直角四面体的顶点作为坐标系的原点,直角四面体的底在坐标系的平面方程为 x a + y b + z c = 1 \frac{x}{a}+\frac{y}{b}+\frac{z}{c}=1 ax+by+cz=1,那么 h h h为原点到该平面方程的直线距离。
h = 1 1 a 2 + 1 b 2 + 1 c 2 h=\frac{1}{\sqrt{\frac{1}{a^2}+\frac{1}{b^2}+\frac{1}{c^2}}} h=a21+b21+c211
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在 [ 1 , n ] [1,n] [1,n]间等概率选取某个数,所有数字出现的次数都是 n n n次,所以 1 a 2 , 1 b 2 , 1 c 2 \frac{1}{a^2},\frac{1}{b^2},\frac{1}{c^2} a21,b21,c21都为[1,n]种的某个 1 i 2 \frac{1}{i^2} i21。
最后求数学期望,每个 a , b , c a,b,c a,b,c都有 n n n种选法,所以一共有 n 3 n^3 n3种,对于每个a,都有 n 2 n^2 n2个。
E ( 1 h 2 ) = n 2 ∗ 3 ∗ ∑ i = 1 n 1 i 2 n 3 ( n ≥ 3 ) E(\frac{1}{h^2})=\frac{n^2*3*\sum_{i=1}^n\frac{1}{i^2}}{n^3}(n\geq3) E(h21)=n3n2∗3∗∑i=1ni21(n≥3)
E ( 1 h 2 ) = 3 ∗ ∑ i = 1 n 1 i 2 n ( n ≥ 3 ) E(\frac{1}{h^2})=\frac{3*\sum_{i=1}^n\frac{1}{i^2}}{n}(n\geq3) E(h21)=n3∗∑i=1ni21(n≥3)
所以只要预处理一下,直接 O ( 1 ) O(1) O(1)得出答案。
#include
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;
#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)
// const ll mod = 1e9 + 7;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;
const ll mod = 998244353;
ll quick_pow(ll a, ll b)
{
ll ans = 1, base = a;
while(b != 0)
{
if(b & 1)
{
ans = ans * base % mod;
}
base = base * base % mod;
b >>= 1;
}
return ans;
}
ll inv[6000005];
ll f[6000005];
void Init()
{
inv[1] = 1;
for(int i = 2;i <= 6000002; i++) {
inv[i] = mod - (mod / i) * inv[mod % i] % mod;
}
}
void solve() {
Init();
for(int i = 1;i <= 6000002; i++) {
f[i] = (f[i - 1] + (inv[i] * inv[i]) % mod) % mod;
}
int T;
scanf("%d",&T);
while(T--) {
ll n;
scanf("%d",&n);
ll k = 3 * f[n] % mod * inv[n] % mod;
printf("%lld\n",k);
}
}
signed main() {
ios_base::sync_with_stdio(false);
//cin.tie(nullptr);
//cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}
赛后又交了已发,发现T了,赛中AC,赛后T了,很迷,最后把cin改成scanf还是对了,差点吓死我。