light oj 1370(欧拉函数题)

https://vjudge.net/problem/LightOJ-1370
这是题目链接供大家练习用:
先介绍一下欧拉函数:
欧拉函数
定义:φ(n) 表示小于等于n的数中与n互质的数的个数。
基本性质:
① φ(1)=1 (很显然)
②对于φ(n),如果n是质数,φ(n) = n - 1。 (也很显然)
③对于φ(n),如果n是质数p的k次方(即n=p^k),对于φ(n) = p^k - p(k-1)。想了半天终于想懂为什么了。n是质数p的k次方,那么除了p的倍数其他的数都跟n互质,p的倍数有多少个呢。自然是n/p个了(相当于15里面有15/3个3的倍数),n/p就是p(k-1)。
④若n.m互质,φ(nm) = φ(n) * φ(m)。
⑤ 当n为奇数时,φ(2*n)=φ(n)。
⑥当n是质数时,φ(n * 2) = φ(n) * φ(2) = φ(n)。
⑦小于N且与N互质的所有数的和是φ(n)*n/2。
分析这个题目大致意思就是:
给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和。
思路:1.用数组存下每个数的欧拉函数值,然后一个个找。
2.利用欧拉函数的性质。对于给定的数x,欧拉函数值大于等于x的数一定大于x,于是我们从x+1开始找,看他之后的每一个数是不是素数,如果是的话,就break。为什么呢,因为纵观刚刚的那些性质我们发现,素数的欧拉函数值最大。所以我们碰到的第一个素数一定是我们要找的数。(意思就是因为有素数的性质得素数的欧拉值最大且为p-1,所以第一个达到要求的值一定为素数。
再次直接附上AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define inf 1000000000
using namespace std;
const int N= 1e6 + 5;
bool no_prime[N];
void init()
{
    no_prime[0] = no_prime[1] = true;
    for(int i = 2;i < N;i++)
    {
        if(no_prime[i])continue;
        for(int j = 2 * i;j < N;j+=i)
        {
            no_prime[j] = true;
        }
    }
}
int main()
{
    init();
    int t;
    cin >> t;
    int Case = 1;
    while(t--)
    {
        long long sum  =0;
        int n;
        cin >> n;
        int x;
        for(int i = 1;i <= n;i++)
        {
            cin >> x;
            for(int j = x + 1;;j++)
            {
                if(!no_prime[j])
                {
                    sum += j;
                    break;
                }
            }
        }
        printf("Case %d: %lld Xukha\n",Case++,sum);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值