公式推导转自:
此题是关于欧拉函数的简单数论题,首先我们先来看看欧拉函数(也称 φ函数):
欧拉函数: 对于给定正整数 n ,少于或等于n的数中与n互质的数的数目。
若n是质数p的i次幂,φ(n)=p^i - p^(i-1)=(p-1)*p^(i-1) (解题关键),因为除了p的倍数外,其他数都跟n互质。
设n为正整数,以 φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值,这里函数
φ:N→N,n→φ(n) 称为欧拉函数。
欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n) [积性函数的形式]。
特殊性质:当n为奇数时,φ(2n)=φ(n), 证明与上述类似
根据欧拉函数,对于给定的 n ,我们总能找到小于 n 的(当 n 为素数时, 等于 n )素数 p1, p2, ··· , pN, 使得
n = (p1 ^ a1) * (p2 ^ a2) * ···· * (pN ^ aN);
所以,
φ(n)=φ(p1 ^ a1) * φ(p2 ^ a2) * ··· * φ(pN ^ aN)
所以,
φ(n) = ((p1 - 1)* p1^(a1 - 1)) * ((p2 - 1)* p2^(a2 - 1)) * ··· * ((pN - 1)* pN^(aN - 1))
首先,我们假设与 n 互质的数(小于 n ) 有 n 个, 事实上它有 φ(n) 个, 我们可以寻找 n 与 φ(n) 的关系来求解:
n / φ(n) = (p1 * p2 * ··· * pN) / ((p1-1) * (p2-1) * ··· *(pN-1))
所以,
φ(n) = (n * (p1-1) * (p2-1) * ··· *(pN-1)) / (p1 * p2 * ··· * pN);
即:
φ(n) = n * ((p1-1) / p1) * ((p2-1) / p2) * ··· * ((pN-1) / pN);
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX_N = 5000005;
unsigned long long num[MAX_N];
void init(){
memset( num, 0, sizeof( num ) );
for( int i = 2; i < MAX_N; i++ ){
if( num[i] == 0 ){
for( int j = i; j < MAX_N; j += i ){
if( num[j] == 0 ) num[j] = j;
num[j] = num[j] / i * ( i - 1 );
}
}
}
for( int i = 2; i < MAX_N; i++ ){
num[i] = num[i] * num[i] + num[i-1];
}
}
int main(){
int a, b, T, Case = 1;
init();
cin >> T;
while( T-- ){
scanf( "%d%d", &a, &b );
printf( "Case %d: %llu\n", Case++, num[b] - num[a-1] );
}
return 0;
}