light oj 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 from a 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

Hint

Euler's totient function  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 is read "phi of n."

Given the general prime factorization of , one can compute  using the formula


  题意:假设所有小于等于x的数中,与x互质的数的个数为n,则sorce(x)=n的平方。给你a和b,求从a到b所有的sorce(i)的和。

其实就是一道简单的欧拉函数的模板题,但是坑点实在太多。


坑点:

1、会爆long long导致wa,应该定义为unsigned long long。

2、不能开两个数组,不然会爆内存。求欧拉函数值的数组和前缀和的数组可以用一个数组表示。

3、不能用cout输出,不然会超时,应该用printf。


#include <bits/stdc++.h>
#define N 5000000+10
using namespace std;
typedef unsigned long long ll;
ll Euler[N];

void  init()
{
    Euler[1]=1;
    for(int i=2; i<N; i++)
        Euler[i]=i;
    for(int i=2; i<N; i++)
        if(Euler[i]==i)
            for(int j=i; j<N; j+=i)
                Euler[j]=Euler[j]/i*(i-1);
}
void solve()
{
    for(int i=2; i<N; i++)
        Euler[i]=Euler[i-1]+Euler[i]*Euler[i];
}

int main()
{
    init();
    solve();
    int t,a,b;
    cin>>t;
    for(int cas=1; cas<=t; cas++)
    {
        scanf("%d%d",&a,&b);
        printf("Case %d: %llu\n",cas,Euler[b]-Euler[a-1]);
    }
    return 0;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值