# HDU6588 经典gcd求和

## 需要求

$\sum_{i=1}^n\gcd(\lfloor{\sqrt[3]{i}}\rfloor,i)\mod 998244353 \quad n = 10^{21}$

## 思路

$m=\lfloor \sqrt[3]{n} \rfloor-1$

$\sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i)$

$f(n) = \sum_{i=1}^ngcd(m,i) \\ = \sum_{i=1}^n \sum_{d|gcd(m,i)}\phi(d) \\ = \sum_{d|m} \phi(d)*\left \lfloor \frac{n}{d} \right \rfloor$

$\sum_{i=1}^{n}gcd(floor(\sqrt[3]{i}),i) = \sum_{i=1}^{m}\sum\limits_{j=i^{3}}^{(i+1)^{3}-1}gcd(i,j) \quad + \quad \sum\limits_{i=(m+1)^{3}}^{n}gcd(m+1,i) \\ = \sum_{i=1}^{m}\sum_{d|i}\phi(d)*\left [ \left \lfloor \frac{(i+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{i^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ \left \lfloor \frac{(id+1)^3 -1}{d} \right \rfloor - \left \lfloor \frac{(id)^3-1}{d} \right \rfloor \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ] \\ = \sum_{d=1}^{m}\phi(d)*\sum_{i=1}^{ \lfloor m/d \rfloor}\left [ 3di^2 + 3i + 1(注意这里是下取整) \right ] \quad + \quad \sum_{d|m+1}\phi(d)*\left [ \left \lfloor \frac{n}{d} \right \rfloor - \left \lfloor \frac{(m+1)^3-1}{d} \right \rfloor \right ]$

## Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int mod = 998244353;
const int inv2 = 499122177;
const int inv6 = 166374059;
const int maxn=1e7+10;
template <class T>
static char ch;static bool neg;
for(ch=neg=0;ch<'0' || '9'<ch;neg|=ch=='-',ch=getchar());
for(x=0;'0'<=ch && ch<='9';(x*=10)+=ch-'0',ch=getchar());
x=neg?-x:x;
}
lll n;
int tot;
bool valid[maxn];//is prime or not
int phi[maxn];// phi
int ans[maxn];// prime
void getprime(int n)
{
tot=0;
phi[1]=1;
memset(valid,true,sizeof(valid));
for(int i=2;i<=n;++i){
if(valid[i]){
tot++;
ans[tot]=i;
phi[i]=i-1;//i为素数
}
//下面的主角是小于等于i的每个质数
for(int j=1;(j<=tot) && (i*ans[j]<=n);++j){
valid[i*ans[j]]=false;
if(i%ans[j]==0){//ans[j]是i的素因子
phi[i*ans[j]]=phi[i]*ans[j];
break;//如果整除就break;
}
else phi[i*ans[j]]=phi[i]*(ans[j]-1);
}
}
}
lll pow3(lll x)
{
return x*x*x;
}
//n(n+1)(2n+1)/6
ll solve(int d, ll m){
ll up = m/d;
ll ans1 = (1+up)*up%mod*inv2%mod;
ll ans2 = d*up%mod*(up+1)%mod*(2*up+1)%mod*inv6%mod;
return ((ans1+ans2)*3 + up)%mod;
}
int main()
{
getprime(1e7);
int t;
cin>>t;
while(t--)
{
int m = pow(n,1.0/3) - 1e5;
for(;pow3(m)<=n;m++);
m-=2;
ll ans = 0;
for(int d=1;d<=m;++d){
ans=(ans + 1LL*phi[d]*solve(d,m)%mod)%mod;
}
ll res = 0;
int now=m+1;
for(int i=1;i*i<=now;++i){
if(now%i==0){//i now/i
res = (res + 1LL*phi[i]*((n/i-(pow3(m+1)-1)/i)%mod) )%mod;
if(i*i!=now) res = (res + 1LL*phi[now/i]*((n/(now/i)-(pow3(m+1)-1)/(now/i))%mod) )%mod;
}
}
ans = (ans + res)%mod;
cout<<ans<<endl;
}
return 0;
}