XTU-OJ 1355-Euler‘s Totient Function

文章讲述了如何使用欧拉筛进阶方法计算给定范围内的欧拉函数值,并结合前缀和求解特定问题f(a,b),涉及对欧拉函数性质的理解和编程实现。

题目描述

对于整数n,定义ϕ(n)为小于或等于n,并与n互质的整数的个数,比如6,比它小的和它互质的数有1,5,所以ϕ(6)=2。 如果n=pk11⋅pk22⋅…⋅pkmm,其中pi为不相同的素数。 那么ϕ(n)=n⋅(1−1p1)⋅…⋅(1−1pm)。

我们定义f(a,b)=∑bi=aϕ(i),请你写一个程序求f(a,b)。

输入

第一行是一个整数T(1≤T≤10000),表示样例的个数。 每个样例是一行,为两个整数a,b(1≤a≤b≤3000000)。

输出

每行输出一个样例的结果。

样例输入

3  
1 6  
1 100  
1 1000000

样例输出

12  
3044  
303963552392

解题思路: 欧拉筛进阶---->欧拉函数  +  前缀和 (老熟人了)

本题是一个很纯粹的模板题,就是计算 欧拉函数 公式(后面离散数学也会提到,话又说回来了,认真学习)。具体的概念解析有个博主写的很好,可以直接学习,点我跳转

AC代码:

#include <stdio.h>

int T,a,b;
const int MAXN = 3e6+5;
bool vis[MAXN];               // 筛选MAXN个素数
int prime[MAXN];              // 把素数依次存放在该数组中
__int64 phi[MAXN] = {0,1};

void oula()
{
    for (int i = 2; i < MAXN; i ++)
    {
        if ( !vis[i])
        {
            prime[++prime[0]] = i;      // prime[0] --> 筛选出的素数个数
            phi[i] = i-1;               // 素数i的  ϕ(i) = i-1;
        }
        for (int j = 1; j <= prime[0] && i <= MAXN/prime[j]; j ++)
        {
            vis[i*prime[j]] = 1;        // 素数prime[j]的i倍为 合数
            phi[i*prime[j]] = phi[i]*phi[prime[j]];
            if (i % prime[j] == 0)
            {
                phi[i*prime[j]] = phi[i]*prime[j];
                break;
            }
        }
    }
    for (int i = 1; i <= 3e6; i ++)
        phi[i] += phi[i-1];
}

int main()
{
    oula();
    scanf("%d",&T);
    while ( T --)
    {
        scanf("%d %d",&a,&b);
        printf("%I64d\n",phi[b]-phi[a-1]);
    }
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值