hdu3501 Calculation 2(欧拉函数)


http://acm.hdu.edu.cn/showproblem.php?pid=3501

题意:求小于n中与n不互为质数的正整数之和。


思路:主要就是欧拉函数的入门。看这个吧:欧拉入门

欧拉函数是为了求小于或等于n的数中与n互质的数的数目。


直接不分所以然就给了个这样的公式:φ(n)=n*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),φ(n)是欧拉函数的值,p1、p2...是素因子的大小。欧拉函数中是每算一个素因子然后乘一项式子。比如说先算n*(1-1/p1),然后算出的ans再乘以(1-1/p2),考虑到省略掉乘法可以降低时间所以把ans乘进去写成了减法;


接着就是完全消除素因子,比如8的素因子2,必须除多次才可完全消除;


最后是未消除素因子的处理,由于上面消因子的时候实际上是改变了n的值,使得原本可以满足判断条件的素因子因为n过小而漏掉,这一步就是为此而存在。不过这个因子不会太大,若是太大就不会被漏掉,所以不必多次消除,一次就可以达到目的。


欧拉函数的扩展:小于或等于n中与n互质的数的和为euler(n)*n/2;

本题中是求与其不互质的数的和。


#include <stdio.h>
#include <algorithm>

using namespace std;

typedef long long ll;

ll euler(ll n)
{
    ll ans = n;
    for(int i = 2; i*i <= n; i++)
    {
        if(n%i == 0)
        {
            ans -= ans/i;
            while(n%i == 0)
                n /= i;//彻底消除当前素因子
        }
    }
    if(n > 1) ans -= ans/n;
    return ans;
}

int main()
{
   // freopen("in.txt", "r", stdin);
    ll n, ans;
    while(~scanf("%lld", &n))
    {
        if(n == 0) break;
        ans = n*(n+1)/2-n;
        ans -= euler(n)*n/2;
        printf("%lld\n", ans%1000000007);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值