Mathematically Hard(欧拉函数)
Mathematically some problems look hard. But with the help of the computer, some problems can be easily solvable.
In this problem, you will be given two integers a and b. You have to find the summation of the scores of the numbers from a to b (inclusive). The score of a number is defined as the following function:
score(x)=n2 ,n<x and gcd(n,x)=1
To illustrate, n is the number of relatively prime numbers with x, which are smaller than x.
For example,
For 6, the relatively prime numbers with 6 are {1, 5}. So, score (6) = 22 = 4.
For 16, the relatively prime numbers with 16 are {1, 3, 5, 7, 9, 11, 13, 15}. So, score (16) = 82 = 64.
Now, you have to solve this task.
Input
Input starts with an integer T (≤ 105), denoting the number of test cases.
Each case will contain two integers a and b (2 ≤ a ≤ b ≤ 5 * 106).
Output
For each case, print the case number and the summation of all the scores from a to b.
Sample Input
3
6 6
8 8
2 20
Sample Output
Case 1: 4
Case 2: 16
Case 3: 1237
Note
Two integers are said to be relatively prime, if the greatest common divisor for them is 1.
Euler’s totient function ϕ(n) applied to a positive integer n is defined to be the number of positive integers less than or equal to n that are relatively prime to n. ϕ(n) is read “phi of n.”
Given the general prime factorization of n=p1e1p2e2…pmem, one can compute ϕ(n) using the formula:
ϕ(n)=n(1−1/p1)(1−1/p2)…(1−1/pm)
题意: 求a-b之间欧拉函数的平方和
注意: 要用unsigned long long,输出用%llu,至于为什么用unsigned long long 应该是数据范围的问题
以下图片来自这里
AC代码:
#include<stdio.h>
#include<string.h>
#define ull unsigned long long
#include<algorithm>
using namespace std;
const int N=5e6+100;
ull o[N],p[N],f[N],cnt;
void ol()
{
ull i,j;
for(i=0;i<N;i++)
o[i]=i;
for(i=2;i<N;i++)
{
if(o[i]==i)//没变是素数
{
for(j=i;j<N;j+=i)
o[j]=o[j]/i*(i-1);
}
}
/* o[1]=1;
for(i=2; i<N; i++)
{
if(!f[i])//素数
{
p[++cnt]=i;//存素数
o[i]=i-1;//素数与前i-1个数都互质
}
for(j=1; j<=cnt&&i*p[j]<=N; j++)
{
f[i*p[j]]=1;//i为素数,i*p[j]一定不为素数
if(i%p[j]==0)
{
o[i*p[j]]=o[i]*p[j];
//对于i%j==0,有p(i*j)=p(i)*j;
//i是j的倍数,j为质数
break;
}
else
o[i*p[j]]=o[i]*(p[j]-1);
//此时gcd(i,j)=1, 有o(i*j)=o(i)*o(j);
//j是质数,故有o(j)=j-1;
}
}*/
for(i=2;i<N;i++)
o[i]=o[i-1]+o[i]*o[i];
}
int main()
{
ull n=1,t,a,b;
scanf("%llu",&t);
ol();//printf("%d %d++\n",o[5],o[6]);
while(t--)
{
scanf("%llu%llu",&a,&b);
printf("Case %llu: %llu\n",n++,o[b]-o[a-1]);
}
return 0;
}