título
pensamiento
Luo Gu significado de las preguntas que un pequeño problema, tendría una traducción directa de la cara del título Inglés
Para la teoría de números, debe deformación violencia
\ (B_i = \ sum_ {a_1 = 1} ^ {i} \ sum_ {a_2 = 1} ^ {i} \ puntos \ sum_ {a_k = 1} ^ {i} [gcd (a_1, a_2 \ cdots, a_k) == 1] \)
Vemos que una parte de la espalda mcd, es fácil pensar en \ (\ mu \)
\ (B_i = \ sum_ {a_1 = 1} ^ {i} \ sum_ {a_2 = 1} ^ {i} \ puntos \ sum_ {a_k = 1} ^ {i} \ sum_ {d | mcd (a_1, a_2 \ cdots, a_k)} \ mu (d) \)
De acuerdo con la rutina
\ (B_i = \ sum_ {d = 1} ^ {i} (\ mu (d) * \ lfloor \ frac {i} {d} \ rfloor ^ k) \)
Después de rutinas divisibles de bloque
A continuación, puede \ (O (\ sqrt n * log_n) \) tiempo de procesamiento de una sola \ (b_i \)
Entonces?
A continuación, las horas extraordinarias
Esto no tiene sentido?
Pensamos acerca de cómo optimizar
En primer lugar ^ luego, no se puede poner en la ecuación, o va a ser muy molesto
Pero nos parecía tener a conocerse \ (b_i \) ,
Consideramos dos diferencias adyacentes
\ (B_i-b_ {i-1} = \ sum_ {d = 1} ^ {i} (\ mu (d) * \ lfloor \ frac {I} {d} \ rfloor ^ k) - \ sum_ {d = 1} ^ {i-1} (\ mu (d) * \ lfloor \ frac {i-1} {d} \ rfloor ^ k) \)
A continuación, nos sorprendió al descubrir que, después de \ (d \) caso identificado
Muchas de las fórmulas se anulan entre sí,
Así que sólo tenemos que calcular esos puntos pueden producir cambios
Es fácil de lanzamiento, sólo si \ (d | i \) , el primero será más grande que el último 1
\ (B_i-b_ {i-1} = \ sum_ {d | i} (\ mu (d) * (\ lfloor \ frac {i} {d} \ rfloor ^ k - (\ lfloor \ frac {i} { d} \ rfloor-1) ^ k) \)
Después?
Después de la potencia k-ésimo de la memoria
La violencia en la que van
La complejidad del tiempo total \ (O (n * log n * log n) \)
código
#include<iostream>
using namespace std;
const long long mod=1e9+7;
int n,k;
int mu[2000005];
int pri[2000005];
int lenp;
bool vis[2000005];
long long b[2000005];
long long ans;
long long mem[2000005];
void oular()
{
mu[1]=1;
for(int i=2;i<=2000000;i++)
{
if(!vis[i])
{
pri[++lenp]=i;
mu[i]=-1;
}
for(int j=1;pri[j]*i<=2000000&&j<=lenp;j++)
{
if(i%pri[j]==0)
{
mu[i*pri[j]]=0;
vis[i*pri[j]]=1;
break;
}
mu[i*pri[j]]=-mu[i];
vis[i*pri[j]]=1;
}
}
}
long long qkpow(long long a,int b)
{
if(b==n&&mem[a]!=0)
return mem[a];
if(b==0)
return 1;
if(b==1)
return a;
long long t=qkpow(a,b/2);
t=t*t%mod;
if(b%2==1)
t=t*a%mod;
if(b==n)
mem[a]=t;
return t;
}
int main()
{
cin>>n>>k;
oular();
for(int i=1;i<=k;i++)
for(int j=1;j*i<=k;j++)
b[i*j]=(b[i*j]+(1ll*(mu[i]+mod)%mod)*(qkpow(j,n)-qkpow(j-1,n)+mod)%mod)%mod;
for(int i=2;i<=k;i++)
{
b[i]=(b[i]+b[i-1])%mod;
ans=(ans+(b[i]^i))%mod;
}
cout<<ans;
return 0;
}