El título es muy conciso, pero no hay nada que hacer durante la inversión de la mañana.
Hacer nln directamente puede simplemente convertir la forma original = \ (\ sum_ {x = 1} ^ n \ frac {n} {x} d (x) \)
De esta manera, hay un método O (n) porque d es una función directa de la función productiva. No es necesario dividir el bloque directamente O (n).
const int MAXN=15000010;
int n,top;
int v[MAXN],g[MAXN],p[1000010],d[MAXN];
inline void prepare()
{
d[1]=1;
rep(2,n,i)
{
if(!v[i])
{
p[++top]=g[i]=v[i]=i;
ll sum=p[top];int j=1;
while(sum<=n)d[sum]=j+1,sum=sum*p[top],++j;
}
rep(1,top,j)
{
if(n/i<p[j])break;
int ww=i*p[j];
v[ww]=p[j];
if(p[j]==v[i])
{
g[ww]=g[i]*p[j];
d[ww]=d[i/g[i]]*d[g[ww]];
break;
}
d[ww]=d[i]*d[p[j]];
g[ww]=p[j];
}
}
}
int main()
{
//freopen("divisor.in","r",stdin);
//freopen("divisor.out","w",stdout);
get(n);
if(n<=15000000)
{
prepare();//put(top);
//rep(1,n,i)put(d[i]);
ll sum=0;
rep(1,n,i)sum=sum+(ll)(n/i)*d[i];
putl(sum);
}
return 0;
}
Presione aquí para ser autista.
función d prefijo y no pantalla teach Du ni una cosa gcd pueden estar sustituidos como \ (d (i) = \ sum_ {x = 1} ^ {I} [(x, i) = x] \) esta cosa Es inútil o difícil de simplificar.
Uno más \ (d (xy) = \ sum_ {i | x} ^ {x} \ sum_ {j | y} ^ {y} [(i, j) = 1] \)
No tiene nada que ver con esta pregunta.
La razón por la que se puede hacer esta pregunta es porque es el prefijo y el problema de especificidad.
\ (d (w) = \ sum_ {x | w} 1 \) Observando esto, puede encontrar que \ (x, \ frac {w} {x} \) es una tupla de dos.
Y \ (\ sum_ {i = 1} ^ n \ sum_ {p | i} d (p) \) observa esto para un i \ (\ frac {i} {p}, d (p) \ ) es decir, \ (\ frac {i} { p}, \ frac {w} {x}, x \)
Este triple contribuirá 1.
Se puede encontrar que se contarán todos los tripletes como xyz <= n.
Y este triple es el único que existe en un número i.
设 x <= y <= z. 若 x <= \ (n ^ {\ frac {1} {3}}, y \ leq \ sqrt (\ frac {n} {x}) \)
Enumera x, y para contar el número de z.
Como x, y, z pueden ser una permutación, multiplique por 6.
Sin embargo, observando la situación del triple anterior, se encuentra que para x == y, esta situación no está organizada, por lo que es lo mismo restar el número correspondiente de veces.
Una muy buena pregunta. En cuanto a la complejidad está cerca de \ (n ^ {\ frac {2} {3}} \) (no lo probaré.
const ll MAXN=100010;
ll n;
int main()
{
freopen("divisor.in","r",stdin);
freopen("divisor.out","w",stdout);
get(n);
ll w1=1,w2=1,ans=0;
while(w1*w1*w1<=n)++w1;--w1;
while(pf(w2)<=n)++w2;--w2;
for(ll i=1;i<=w1;++i)
{
ll ww=n/i;
for(ll j=i;j*j<=ww;++j)ans+=ww/j-j+1;
}
ll cnt=0;
for(ll i=1;i<=w2;++i)cnt+=n/i/i;
putl(ans*6-cnt*3-2*w1);
return 0;
}