题目
Problem Description
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
题解
当前由a、b、c三条边组成的直角四面体所成的高h
求1/h^2的期望值,一下是数学推论过程(大佬网图借鉴)
然后便是逆元问题
逆元产生的原因便是由于
除法mod存在精度误差 |
---|
(a * b)mod c == (a mod c * b mod c) mod c |
(a + b)mod c == (a mod c + b mod c) mod c |
(a - b)mod c == (a mod c - b mod c) mod c |
(a / b)mod c != (a mod c / b mod c) mod c |
因此把(a / b)mod c == (a * b^(-1))mod c
具体推导就不做了
代码
下面展示一些 内联代码片
。
#include<list>
#include<string.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<deque>
#include<stack>
#include<queue>
#include<set>
#include<iomanip>
#include<cstdlib>
#include<stdexcept>
#include<fstream>
#include<iterator>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 6e6 + 10;
const int inf = 0x3f3f3f3f;
const int Base = 131;
const ll INF = 1ll << 62;
//const double PI = acos(-1);
const double eps = 1e-7;
const int mod = 998244353;
#define mem(a,b) memset(a,b,sizeof(a))
#define speed {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); }
ll a[maxn]; ll n, t, sum[maxn];
ll quick_pow(ll a, ll b)
{
ll ans = 1;
while (b) {
if (b & 1) ans = (ans * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return ans;
}
//逆元函数 公式为 (a/b)%mod=(a*b^(mod-2))%mod
ll inv(ll a, ll b)
{
return (a * quick_pow(b, mod - 2)) % mod;
}
inline ll read() {
ll s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch>'9') { if (ch == '-')w = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
void init() {
a[0] = 0;
for (ll i = 1; i <= 6e6; i++) {
a[i] =(a[i-1]+inv(1, (i * i)%mod))%mod;
}
}
int main()
{
init();
t=read();
while (t--) {
n = read();
printf("%lld\n",(3ll * a[n] * inv(1, n)) % mod);
}
}