快速求欧拉函数

 

hdu2824 快速求欧拉函数

标签: integeroutputeachlessinput百度
  3499人阅读  评论(0)  收藏  举报
  分类:

目录(?)[+]

欧拉函数的定义可以自己百度 phi(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pn)

主要是涉及到求很多个欧拉函数时的求法,这种题一般都是先初始化,

其中,在求素因子的时候处理的很巧妙,当phi[i]==i时,i就是素因子(可以拿起笔在草稿上画一下就明白了),这个时候j+=i, 则j有素因子i,认真思考!

之前做过一道题,是求一个数的所以因子之和,也是类似的做法:

Problem Description

  The hardest problem may not be the real hardest problem.
  Given a natural number n (1 <= n <= 500000), please output the summation of all its proper divisors. Definition: A proper divisor of a natural number is the divisor that is strictly less than the number. e.g. number 20 has 5 proper divisors: 1, 2, 4, 5, 10, and the divisor summation is: 1 + 2 + 4 + 5 + 10 = 22.

Input

An integer stating the number of test cases (equal to about 200000), and that many lines follow, each containing one integer between 1 and 500000 inclusive.

Output

One integer each line: the divisor summation of the integer given respectively.

Sample Input

3
2
10
20

Sample Output

1
8
22

关键代码如下:

[cpp]  view plain  copy
  1. void init()  
  2. {  
  3.  int i, j;  
  4.  memset(a, 0, sizeof(a));  
  5.  for (i = 1; i < 500001; i++)  
  6.   for (j = i + i; j < 500001; j += i)  
  7.    a[j] += i;  //a[j]表示j的所有因子之和,不包括本身  
  8. }  
欧拉定理

早就看到了防止忘记先码上

这个题首先我们要会欧拉定理

b % p = a (b % phi(p)) % p

但是这个有一个前提,a和p必须互质,如果不互质的话是不对的。

但是有一个大神告诉我,不互质的情况下也有一个类似的定理。。
如果a和p不互质,且b大于等于phi(p)

b % p = a (b % phi(p) + phi(p)) % p


hdu2824本题的代码如下:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cmath>  
  4.   
  5. using namespace std;  
  6.   
  7. #define bint __int64  
  8. #define N 3000001  
  9.   
  10. bint phi[N];  
  11.   
  12. void init()  
  13. {  
  14.     int i, j;  
  15.     for(i = 1; i < N; i++)  
  16.         phi[i] = i;  
  17.   
  18.     for(i = 2; i < N; i++)  
  19.         if(i == phi[i]) //此时i为素数  
  20.             for(j = i; j < N; j += i)  //j累加i  
  21.                 phi[j] = (phi[j] / i) * (i - 1); //j有因子i,而且i是素数,正是欧拉函数  
  22. }  
  23.   
  24. int main()  
  25. {  
  26.     init();  
  27.     int a, b;  
  28.     while(scanf("%d%d", &a, &b) != EOF)  
  29.     {  
  30.         bint ans = 0;  
  31.         for(int i = a; i <= b; i++)  
  32.             ans += phi[i];  
  33.         printf("%I64d\n", ans);  
  34.     }  
  35.     return 0;  
  36. }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值