题目看这里
一个简单的反演题目:
∑i=1n∑j=1nϕ(gcd(ϕ(i),ϕ(j)))
∑
i
=
1
n
∑
j
=
1
n
ϕ
(
g
c
d
(
ϕ
(
i
)
,
ϕ
(
j
)
)
)
首先做一下变换
∑ni=1∑nj=1ϕ(gcd(ϕ(i),ϕ(j))) ∑ i = 1 n ∑ j = 1 n ϕ ( g c d ( ϕ ( i ) , ϕ ( j ) ) )
=∑nd=1ϕ(d)∗f(d) = ∑ d = 1 n ϕ ( d ) ∗ f ( d )
这里 f(d)=∑i,j[gcd(ϕ(i),ϕ(j))=d] f ( d ) = ∑ i , j [ g c d ( ϕ ( i ) , ϕ ( j ) ) = d ]
表示有多少对i,j满足它们的 ϕ ϕ 值的最大公约数为d
我们令 F(d)=∑i,j[d|gcd(ϕ(i),ϕ(j))] F ( d ) = ∑ i , j [ d | g c d ( ϕ ( i ) , ϕ ( j ) ) ] ,就有 F(n)=∑n|df(d) F ( n ) = ∑ n | d f ( d )
反演得到 f(n)=∑dF(n∗d)∗μ(d) f ( n ) = ∑ d F ( n ∗ d ) ∗ μ ( d )
所以原式可以写成 ∑i∗j<=nϕ(i)∗F(i∗j)∗μ(j) ∑ i ∗ j <= n ϕ ( i ) ∗ F ( i ∗ j ) ∗ μ ( j )
预处理 μ,ϕ μ , ϕ 和 F F 的值就可以了
#pragma G++ optimize("O3") # p r a g m a G + + o p t i m i z e ( " O 3 " )
#include<stdio.h> # i n c l u d e < s t d i o . h >
#include<string.h> # i n c l u d e < s t r i n g . h >
#include<algorithm> # i n c l u d e < a l g o r i t h m >
#define N 2000010 # d e f i n e N 2000010
#define LL long long # d e f i n e L L l o n g l o n g
using namespace std; u s i n g n a m e s p a c e s t d ;
int n,T; long long S; i n t n , T ; l o n g l o n g S ;
int w[N>>2],t,phi[N],mu[N],vis[N],c[N]; i n t w [ N >> 2 ] , t , p h i [ N ] , m u [ N ] , v i s [ N ] , c [ N ] ;
inline LL F(int x){ return (LL)c[x]∗c[x]; } i n l i n e L L F ( i n t x ) { r e t u r n ( L L ) c [ x ] ∗ c [ x ] ; }
inline void cal(){ i n l i n e v o i d c a l ( ) {
scanf("%d",&n); memset(c,S=0,sizeof c); s c a n f ( " % d " , & n ) ; m e m s e t ( c , S = 0 , s i z e o f c ) ;
for(int i=1;i<=n;++i) ++c[phi[i]]; f o r ( i n t i = 1 ; i <= n ; + + i ) + + c [ p h i [ i ] ] ;
for(int i=1;i<=n;++i) f o r ( i n t i = 1 ; i <= n ; + + i )
for(int j=i+i;j<=n;j+=i) c[i]+=c[j]; f o r ( i n t j = i + i ; j <= n ; j + = i ) c [ i ] + = c [ j ] ;
for(int i=1;i<=n;++i) if(mu[i]) f o r ( i n t i = 1 ; i <= n ; + + i ) i f ( m u [ i ] )
for(int j=1;i∗j<=n;++j) f o r ( i n t j = 1 ; i ∗ j <= n ; + + j )
S+=(LL)F(i∗j)∗mu[i]∗phi[j]; S + = ( L L ) F ( i ∗ j ) ∗ m u [ i ] ∗ p h i [ j ] ;
printf("%lld",S); p r i n t f ( " % l l d " , S ) ;
} }
int main(){ i n t m a i n ( ) {
phi[1]=mu[1]=1; p h i [ 1 ] = m u [ 1 ] = 1 ;
for(int i=2;i<=2000000;++i){ f o r ( i n t i = 2 ; i <= 2000000 ; + + i ) {
if(!vis[i]){ mu[w[++t]=i]=−1; phi[i]=i−1; } i f ( ! v i s [ i ] ) { m u [ w [ + + t ] = i ] = − 1 ; p h i [ i ] = i − 1 ; }
for(int j=1,k;(k=i∗w[j])<=2000000;++j){ f o r ( i n t j = 1 , k ; ( k = i ∗ w [ j ] ) <= 2000000 ; + + j ) {
vis[k]=1; v i s [ k ] = 1 ;
if(i%w[j]==0){ phi[k]=phi[i]∗w[j]; mu[k]=0; break; } i f ( i % w [ j ] == 0 ) { p h i [ k ] = p h i [ i ] ∗ w [ j ] ; m u [ k ] = 0 ; b r e a k ; }
phi[k]=phi[i]∗(w[j]−1); mu[k]=−mu[i]; p h i [ k ] = p h i [ i ] ∗ ( w [ j ] − 1 ) ; m u [ k ] = − m u [ i ] ;
} }
} }
for(scanf("%d",&T);T−−;cal()); f o r ( s c a n f ( " % d " , & T ) ; T − − ; c a l ( ) ) ;
} }