首先考慮分塊,按照 的大小分塊得到
設 ,化簡得到 (化簡過程無法證明,也看不懂題解,我太菜了)
所以原式可以化成
右邊直接枚舉因子,可以在 求出來,所以我們考慮化簡左邊的式子,枚舉 得到
用常見的整除分塊,預處理 前綴和,就可以在 求出來
所以原式
整體複雜度
#include <bits/stdc++.h>
#define ll long long //T了就換int 試試
#define int128 __int128
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 1e7 + 5;//用板子前先改範圍
bool check[MAXN + 10];//值爲 false 表示素數,值爲 true 表示非素數
int phi[MAXN + 10];//歐拉函數表
int prime[MAXN + 10];//連續素數表
//int mu[MAXN + 10];//莫比烏斯函數
int tot;//素數的個數(從0開始
ll sub[MAXN + 10];
ll subi[MAXN + 10];
const ll mod = 998244353;
const ll inv2 = (mod + 1) / 2;
const ll inv6 = (mod + 1) / 6;
void jzk()
{
//memset(check, false, sizeof(check));
phi[1] = 1;
//mu[1] = 1;
check[1] = true;
tot = 0;
for (int i = 2; i < MAXN; i++)
{
if (!check[i])
{
prime[tot++] = i;
phi[i] = i - 1;
//mu[i] = -1;
}
for (int j = 0; j < tot; j++)
{
if (i * prime[j] >= MAXN)
break;
check[i * prime[j]] = true;
if (i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
//mu[i * prime[j]] = 0;
break;
}
else
{
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
//mu[i * prime[j]] = -mu[i];
}
}
}
for (int i = 1; i < MAXN; i++)
{
sub[i] = (sub[i - 1] + phi[i]) % mod;
subi[i] = (subi[i - 1] + (ll)phi[i] * i) % mod;
}
}
ll ck(int128 n)
{
int128 l = 1, r = /*1e4;*/1e7;
while (l + 1 < r)
{
int128 k = (l + r) / 2;
if (k * k * k > n)
r = k;
else
l = k;
}
if (r * r * r <= n)
l = r;
return (ll)l;
}
ll calc2(ll n)
{
return n * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod;
}
ll calc1(ll n)
{
return n * (n + 1) % mod * inv2 % mod;
}
ll calc0(ll n)
{
return n;
}
inline int128 read()
{
int128 X = 0, w = 0; char ch = 0;
while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline void print(int128 x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
int main()
{
//freopen("test1.in","r",stdin);
jzk();
int T;
sc("%d", &T);
while (T--)
{
int128 n;
n = read();
//sc("%lld", &n);
int128 ans = 0;
ll n3 = ck(n);
int128 n33 = (int128)n3 * n3 * n3;
ll j;
for (ll T = 1; T <= n3 - 1; T = j + 1)
{
/*ll res = (3 * T * calc2((n3 - 1) / T) % mod + 3 * calc1((n3 - 1) / T) % mod + calc0((n3 - 1) / T)) % mod;
res = res * phi[T];*/
j = (n3 - 1) / ((n3 - 1) / T);
ll res = ((subi[j] - subi[T - 1] + mod) * 3 * calc2((n3 - 1) / T) % mod + (sub[j] - sub[T - 1] + mod) * 3 * calc1((n3 - 1) / T) % mod + (sub[j] - sub[T - 1] + mod) * calc0((n3 - 1) / T) % mod) % mod;
ans = (ans + res) % mod;
}
for (ll T = 1; T * T <= n3; T++)
{
if (n3 % T == 0)
{
ans = (ans + phi[T] * ((n / T) - ((n33 - 1) / T) + mod)) % mod;
if (T * T != n3)
ans = (ans + phi[n3 / T] * ((n / (n3 / T)) - ((n33 - 1) / (n3 / T)) + mod)) % mod;
}
}
print(ans);
putchar('\n');
//pr("%lld\n", ans);
}
}