LightOJ-1007-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 froma to b (inclusive). The score of a number is defined as the following function.
score (x) = n2, where 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 and 5. So, score (6) = 22 = 4.
For 8, the relatively prime numbers with 8 are 1, 3, 5 and 7. So, score (8) = 42 = 16.
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
题意:
不是求区间内素数个数的平方和,是求区间内欧拉函数值的平方和
思路:欧拉函数打表(模板)+前缀和+预处理不然TLE
求欧拉函数1-N的打表模板:
1 void init() 2 { 3 memset(ans,0,sizeof(ans));//一定要清空 4 ans[1]=1; 5 for(int i=2; i<=N; i++) 6 { 7 if(ans[i]==0) 8 { 9 for(int j=i; j<=N; j+=i) 10 { 11 if(ans[j]==0) 12 { 13 ans[j]=j; 14 } 15 ans[j]=ans[j]/i*(i-1); 16 } 17 18 } 19 } 20 }
1 #include<stdio.h> 2 #include<map> 3 #include<string.h> 4 #include<iostream> 5 typedef long long ll; 6 using namespace std; 7 8 const int N=5*1e6+10; 9 unsigned long long ans[N];//unsigned long long输出是%llu,long long会爆,前者20位,后者19位 10 11 void init() 12 { 13 memset(ans,0,sizeof(ans));//一定要清空,不然WA 14 ans[1]=1; 15 for(int i=2; i<=N; i++) 16 { 17 if(ans[i]==0) 18 { 19 for(int j=i; j<=N; j+=i) 20 { 21 if(ans[j]==0) 22 { 23 ans[j]=j; 24 } 25 ans[j]=ans[j]/i*(i-1); 26 } 27 28 } 29 }//欧拉函数打表 30 for(int i=1; i<=N; i++) 31 { 32 ans[i]=ans[i-1]+ans[i]*ans[i];//计算前缀和 33 } 34 } 35 int main() 36 { 37 init(); 38 int tt=1,t; 39 scanf("%d",&t); 40 while(t--) 41 { 42 int a,b; 43 scanf("%d %d",&a,&b); 44 printf("Case %d: %llu\n",tt++,ans[b]-ans[a-1]);//取区间,左端区间-1,别弄错了 45 } 46 47 return 0; 48 }