链接
https://nanti.jisuanke.com/t/38226
题解
各种推式子,最后发现答案是
∑
i
=
1
n
f
(
⌊
n
i
⌋
)
i
3
∑
d
∣
i
μ
(
d
)
φ
(
i
d
)
\sum_{i=1}^nf(\lfloor\frac{n}{i}\rfloor)i^3\sum_{d|i}\mu(d)\varphi(\frac{i}{d})
i=1∑nf(⌊in⌋)i3d∣i∑μ(d)φ(di)
其中
f
(
n
)
=
n
n
(
n
+
1
)
2
n
(
n
+
1
)
(
2
n
+
1
)
6
f(n)=n\frac{n(n+1)}{2}\frac{n(n+1)(2n+1)}{6}
f(n)=n2n(n+1)6n(n+1)(2n+1)
复杂度
O
(
n
+
T
n
)
O(n+T\sqrt {n})
O(n+Tn)
代码
#include <bits/stdc++.h>
#define eps 1e-8
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define cl(x) memset(x,0,sizeof(x))
#define mod 1073741824ll
#define maxn 10000010
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
int c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
int prime[1000000], g[maxn], S[maxn], f[maxn], pmin[maxn], pprd[maxn];
bool mark[maxn];
void init()
{
int i, j;
for(i=2;i<maxn;i++)
{
// printf("i=%d\n",i);
// fflush(stdout);
if(!mark[i]){prime[++*prime]=i;pmin[i]=pprd[i]=i;}
for(j=1;j<=*prime and i*prime[j]<maxn;j++)
{
mark[i*prime[j]]=1;
pmin[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
pprd[i*prime[j]]=pprd[i]*prime[j];
break;
}
else
{
pprd[i*prime[j]]=prime[j];
}
}
}
// phi[1]=mu[1]=g[1]=1;
g[1]=1;
for(i=2;i<maxn;i++)
{
if(i==pprd[i])
{
// phi[i]=i/pmin[i]*(pmin[i]-1);
// mu[i]=-!mark[i];
// g[i]=mu[1]*phi[i]+mu[pmin[i]]*phi[i/pmin[i]];
g[i]=i/pmin[i]*(pmin[i]-1);
if(pmin[i]==i)
{
g[i]-=1;
}
else
{
g[i]-=i/pmin[i]/pmin[i]*(pmin[i]-1);
}
}
else
{
// phi[i]=phi[i/pprd[i]]*phi[pprd[i]];
// mu[i]=mu[i/pprd[i]]*mu[pprd[i]];
g[i]=g[i/pprd[i]]*g[pprd[i]];
}
if(i<=10)
{
// printf("g[%d]=%d\n",i,g[i]);
}
}
// for(i=1;i<=10;i++)
// {
// printf("i=%d phi=%d mu=%d\n",i,phi[i],mu[i]);
// }
// fflush(stdout);
int s1=0, s2=0;
for(i=1;i<maxn;i++)
{
s1+=i;
s2+=i*i;
f[i]=i*s1*s2;
S[i]=S[i-1]+i*i*i*g[i];
}
// printf("cnt=%d\n",*prime);
}
int main()
{
// printf("M=%d\n",sizeof(phi)*7/1024);
int T=read(), N, i, last, ans;
init();
// for(i=1;i<=10;i++)
// printf("g[%d]=%d\n",i,g[i]);
while(T--)
{
N=read();
ans=0;
for(i=1;i<=N;i=last+1)
{
last = N/(N/i);
ans += f[N/i]*(S[last]-S[i-1]);
}
// for(i=1;i<=N;i++)
// {
// ans += f[N/i]*i%mod*i%mod*i%mod*g[i];
// ans %= mod;
// }
printf("%d\n",ans&((1<<30)-1));
}
return 0;
}