P1891 louco LCM

O significado de problemas

\ (\ sum_ {i = 1} ^ n \ operatorname {} LCM (i, n) \)
多测, \ (T \ leq 3 \ cdot 10 ^ 5,1 \ leq n \ leq 10 ^ 6 \)


solução do problema

Olhada neste intervalo de dados, para saber um pré-tratamento + \ (O (1) \) consulta ou algo assim
, é fácil pensar em variantes:

\ [\ Sum_ {i = 1} ^ n \ operatorname {lcm} (i, n) = \ sum_ {i = 1} ^ n \ frac {i \ CDOT n} {\ GCD (i, n)} = n \ sum_ {i = 1} ^ n \ frac {i} {\ GCD (i, n)} \]

Então não seria o

Na verdade, é adicionar uma camada de \ (\ SUM \) , não olhar para esta solução problema é bastante inesperado, mas isso pode ser uma coisa muito rotineira?

\ [N \ sum_ {d | n} \ sum_ {i = 1} ^ n \ frac {i} {d} \ cdot [\ GCD (i, n) = d] \]

Embora pareça uma porcaria, mas crítica

Em seguida, deformada em parênteses divididas por \ (D \) torna-se \ (\ GCD (\ dfrac {i} {D}, \ {n-dfrac} {D}) =. 1 \) , de facto, se o \ (\ dfrac {i} {d} \ ) e \ (\ dfrac {n} { d} \) primo, então eles são multiplicados por \ (d \) após \ (\ GCD \) é \ (d \)

\ [N \ sum_ {d | n} \ sum_ {i = 1} ^ n \ frac {i} {d} \ cdot [\ GCD (\ frac {i} {d}, \ frac {n} {d}) = 1] \]

Em seguida, deixou \ (I \) Alternativamente \ (\ dfrac {i} { d} \)

\ [N \ sum_ {d | n} \ sum_ {i = 1} ^ {\ frac {n} {d}} i \ cdot [\ GCD (i, \ frac {n} {d}) = 1] \ ]

E porque o \ (\ dfrac {n} { d}, d \) é \ (n- \) do fator de "um par", então esta equação pode ser escrita diretamente na forma de uma melhor aparência:

\ [N \ sum_ {d | n} \ sum_ {i = 1} ^ {d} i \ cdot [\ GCD (i, d) = 1] \]

É um pouco depois Euler \ (\ varphi \) significa que a função
fundamental é que \ (i \) é uma monstruosidade, então é claro que você quer é olhar para a onda de solução do problema

Por causa de \ (\ mdc (i, d
) = \ mdc (di, d) \) a euclidiana eo método \ (\ GCD \) como, particularmente provado aqui olhar
isso considero \ (\ sum_ {i = 1} ^ {d} i \ cdot [\ GCD (i, d) = 1] \) em cada \ (I \) e \ (DI \) , se o \ (\ GCD (i, d ) \ neq 1 \) certamente não, e quando ele é igual a \ (1 \) , em seguida, estes dois valores é \ (d \)
, em seguida, o número de \ (\ GCD (i, d ) = \ GCD (di, d) = 1 \) ? Certamente \ (\ dfrac {\ varphi (D)} {2} \) , Note aqui que o número de
que é fácil de encontrar, \ (. 1 D = \) são as fórmulas acima para \ (0 \) , e não se sustenta, deve ser dada (\ \ sum) \ moléculas mais \ (1 \) e, em seguida, para baixo arredondada, para evitar esta situação
e resposta mais precisa seria expresso como:

\ [N \ sum_ {d | n} \ lfloor \ frac {\ varphi (d) \ cdot d + 1} {2} \ rfloor \]

Na verdade, quando já \ (O (\ sqrt n) \) resposta, mas pode fazer melhor

\ (O (N \ log \ log n) \) corri um processo de serigrafia semelhante Eppendorf, definimos \ (F_j = \ sum_ {d | j} \ lfloor \ dfrac {\ varphi (d) \ d + cdot {2}}. 1 \ rfloor \) , que deve saber Eppendorf peneira \ (J \) representam geralmente o que
é, em seguida, para cada enumeração para \ (I \) , de facto, cada uma das fórmulas anteriores \ (D \) , e, em seguida, para pressionar a fórmula \ (F_j \) mais o suficiente


pequeno resumo

Claro, eu faço questão poderia dizer muito pouco incompleta
fato de que \ (\ mdc, \ operatorname { LCM} \) questões relacionadas, muitos dos quais são convertidos em \ ([\ gcd = \ cdots ] \ times \ cdots \) forma, \ (\ \ cdots) é o número, e, em seguida, \ (\ varphi \) combinado
, por vezes, esta forma é convertido por adição de um \ (\ sum_ {D | n-} \) , outros não satisfeitas , reuniu-se poderia escrever aqui
de qualquer maneira \ (\ gcd \) este é o mais fácil pensar em \ (\ varphi \) um

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int n=1e6;
LL phi[1000006],f[1000006];
int prime[500006],notprime[1000006];
inline void get_phi(){
	phi[1]=1;
	for(reg int i=2;i<=n;i++){
		if(!notprime[i]) prime[++prime[0]]=i,phi[i]=i-1;
		for(reg int j=1;j<=prime[0]&&i*prime[j]<=n;j++){
			notprime[i*prime[j]]=1;
			if(!(i%prime[j])){
				phi[i*prime[j]]=prime[j]*phi[i];
				break;
			}
			else phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}
int main(){
	get_phi();
	for(reg int i=1;i<=n;i++)
		for(reg int j=i;j<=n;j+=i)
			f[j]+=(phi[i]*i+1)>>1;//要加1,如果i=1的话式子就是1了符合要求,如果不是和没加一样不用管 
	int T=read();while(T--){
		n=read();
		std::printf("%lld\n",f[n]*n);
	}
	return 0;
}

Acho que você gosta

Origin www.cnblogs.com/suxxsfe/p/12624033.html
Recomendado
Clasificación