设为首页 加入收藏

TOP

poj 2478 Farey Sequence(基于素数筛法求欧拉函数)
2015-07-24 05:57:19 来源: 作者: 【 】 浏览:5
Tags:poj 2478 Farey Sequence 基于 素数 函数

http://poj.org/problem?id=2478


求欧拉函数的模板。

初涉欧拉函数,先学一学它基本的性质。

1.欧拉函数是求小于n且和n互质(包括1)的正整数的个数。记为φ(n)。

2.欧拉定理:若a与n互质,那么有a^φ(n) ≡ 1(mod n),经常用于求幂的模。

3.若p是一个质数,那么φ(p) = p-1,注意φ(1) = 1。

4.欧拉函数是积性函数:

若m与n互质,那么φ(nm) = φ(n) * φ(m)。

若n = p^k且p为质数,那么φ(n) = p^k - p^(k-1) = p^(k-1) * (p-1)。

5.当n为奇数时,有φ(2*n) = φ(n)。

6.基于素数筛的求欧拉函数的重要依据:

设a是n的质因数,若(N%a == 0 && (N/a)%a == 0) 则 φ(N) = φ(N/a)*a; 若(N%a == 0 && (N/a)%a != 0) 则φ(N) = φ(N/a)*(a-1)。


该题就是基于性质六,在线性时间内求欧拉函数。

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
       #include 
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #define LL long long #define _LL __int64 #define eps 1e-8 #define PI acos(-1.0) using namespace std; const int maxn = 1000010; const int INF = 0x3f3f3f3f; int n; LL num[maxn]; LL phi[maxn]; //对应φ(i) int flag[maxn]; //flag[i] = 0说明i是素数,否则不是素数 int prime[maxn];//存素数 void get_phi() { int i,j,k; memset(flag,0,sizeof(flag)); phi[1] = 1; k = 0; for(i = 2; i <= maxn; i++) { if(!flag[i]) //i是素数 { phi[i] = i-1; prime[++k] = i; } for(j = 1; j <= k && prime[j]*i <= maxn; j++) { flag[i*prime[j]] = 1; if(i % prime[j] == 0) phi[i*prime[j]] = phi[i] * prime[j]; else phi[i*prime[j]] = phi[i] * (prime[j]-1); } } } int main() { get_phi(); num[1] = 0; for(int i = 2; i <= maxn; i++) num[i] = num[i-1] + phi[i]; while(~scanf("%d",&n)&&n) printf("%lld\n",num[n]); return 0; } 
            
           
          
         
        
       
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 1789-Truck History 下一篇leetcode――Reverse Linked List..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: