题目描述
对 x>1x>1x>1 的整数 xxx ,定义 d(x)d(x)d(x) 是满足 y∣xy|xy∣x(y∣xy | xy∣x 表示 yyy 是 xxx 的约数)且大于 111 的最小的整数。
有一个神奇的函数 f\rm ff ,定义域为正整数且满足以下条件:
对于给定的 nnn, 求 ∑i=1nf(i)\sum_{i=1}^nf(i)∑i=1nf(i) 。
输入描述
本题每个测试点有多组数据,第 111 行一个整数 TTT 表示数据组数。
接下来 TTT 行,每行一个整数 nnn , 含义见题目描述。
- 1≤T≤101\le T\le 101≤T≤10
- 1≤n≤10131\le n \le 10^{13}1≤n≤1013
输出描述
输出 TTT 行,每行一个整数,表示该组数据的答案。
样例输入 1
5 4 10 233 6666 123456
样例输出 1
5 14 513 21610 510126
提示
对于样例1的第1组数据:
f(1)=1f(1)=1\\f(1)=1
d(2)=2, f(2)=f(1)=1d(2)=2,\ f(2)=f(1)=1\\d(2)=2, f(2)=f(1)=1
d(3)=3, f(3)=f(1)=1d(3)=3,\ f(3)=f(1)=1\\d(3)=3, f(3)=f(1)=1
d(4)=2, f(4)=2×f(1)=2d(4)=2,\ f(4)=2\times f(1)=2\\d(4)=2, f(4)=2×f(1)=2
∑i=14f(i)=5\sum_{i=1}^4f(i)=5∑i=14f(i)=5
#include <bits/stdc++.h>
using namespace std;
const long long N=5e6+50;
long long prime[N];
bool vis[N];
long long euler[N];
void prime_euler()
{
memset(vis,0,sizeof(vis));
memset(euler,0,sizeof(euler));
euler[1]=1;
vis[0]=vis[1]=1;
long long tot=1;
for(long long i=2; i<N; i++)
{
if(!vis[i])
{
prime[tot++]=i;
euler[i]=i-1;
}
for(long long j=1; j<tot; j++)
{
if(i*prime[j]>N)
break;
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
euler[i*prime[j]]=euler[i]*prime[j];
break;
}
else
euler[i*prime[j]]=euler[i]*(prime[j]-1);
}
}
}
int main()
{
prime_euler();
long long t;
long long n;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
long long tmp=sqrt(n);
long long ans=0;
for(long long i=1;i<=tmp;i++)
ans+=euler[i]*(n/(i*i));
cout<<ans<<'\n';
}
return 0;
}