欧拉函数学习笔记整理 POJ 2407+POJ 1284+POJ 2478+POJ 3090

38 篇文章 0 订阅
8 篇文章 0 订阅

定义

欧拉函数φ(x)代表1-x中与x互质的数的个数。

基本相关性质

1.设 x=a1p1a2p2...anpn x = a 1 p 1 ∗ a 2 p 2 ∗ . . . ∗ a n p n
则φ(x)= x(11a1)(11a2)...(11an) x ∗ ( 1 − 1 a 1 ) ∗ ( 1 − 1 a 2 ) ∗ . . . ∗ ( 1 − 1 a n ) ;
2.当gcd(m,n)=1时,φ(mn)=φ(m)*φ(n);
3.当x为质数时,φ(x)=x-1,当x为奇数时,φ(2x)=x-1;
4.若x= pk p k ,则 φ(x)=pkpk1=(p1)pk1; φ ( x ) = p k − p k − 1 = ( p − 1 ) p k − 1 ;
5.当p为质数时,
 (1)若满足p|n且 p2n p 2 ∤ n φ(n)=φ(np)(p1) φ ( n ) = φ ( n p ) ∗ ( p − 1 ) ;

 (2)若满足p|n且 p2|n p 2 | n φ(n)=φ(np)p φ ( n ) = φ ( n p ) ∗ p ;

6.当n>1时,1-n中与n 互质的数的整数和为 nφ(n)2 n ∗ φ ( n ) 2

7. d|nφ(d)=n ∑ d | n φ ( d ) = n

证明:(1)若n==1,φ(n)=1=n;

   (2)若n为质数时,φ(n)=n-1,则φ(n)+φ(1)=(n-1)+1=n;

   (3)若 n=pk n = p k ,且p为质数,k>1,

     d|nφ(d)=φ(1)+φ(p)+φ(p2)+...+φ(pk) ∑ d | n φ ( d ) = φ ( 1 ) + φ ( p ) + φ ( p 2 ) + . . . + φ ( p k )

     =1+(p1)+p(p1)+p2(p1)+...+pk(p1) = 1 + ( p − 1 ) + p ( p − 1 ) + p 2 ( p − 1 ) + . . . + p k ( p − 1 )

     =1+(p1)1pk1p=pk=n = 1 + ( p − 1 ) 1 − p k 1 − p = p k = n ;
   (4)n含有多个质因子,即 n=a1p1a2p2...anpn n = a 1 p 1 a 2 p 2 . . . a n p n ,

     d|nφ(d)=p1i1=0p2i2=0...pnin=0φ(a1i1a2i2...anin) ∑ d | n φ ( d ) = ∑ i 1 = 0 p 1 ∑ i 2 = 0 p 2 . . . ∑ i n = 0 p n φ ( a 1 i 1 a 2 i 2 . . . a n i n )

8.欧拉定理:若gcd(a,n)=1,有 aφ(n)1(mod  n) a φ ( n ) ≡ 1 ( m o d     n )

 费马定理:若gcd(a,p)=1,则 ap11(mod  p)    a p − 1 ≡ 1 ( m o d     p )       (将φ(p)=p-1带入欧拉定理)。
9.快速求出欧拉函数的值(P为N的质因子)
若(N%P==0&&(N/P)%P==0) 则有:E(N)=E(N/P)*P;
若(N%P==0&&(N/P)%P!=0) 则有:E(N)=E(N/P)*(P-1)

相关题目

POJ 2407 Relatives(基础题)

POJ 2407题目链接

很直白的使用欧拉函数

#include <iostream>
#include<cstdio>
using namespace std;
int n;
void cal()
{
    int ans=n;
    int t=n;
    for(int i=2; t>1; i++)
    {
        if(t%i==0)
        {
            while(t%i==0)
            {
                t/=i;
            }
            ans=ans-ans/i;
        }
    }
    cout<<ans<<endl;
}
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        cal();
    }
    return 0;
}
POJ 1284 Primitive Roots(+原根)

POJ 1284题目链接

主要涉及一个有关原根的定理,
定理:如果p有原根,则它具有φ(φ(n))个不同的原根,又因为p为质数,所以φ(p)=p-1,所以有φ(p-1)个原根。

#include <iostream>
#include<cstdio>
using namespace std;
#define ll __int64
int n;
void cal()
{
    int ans=n;
    int t=n;
    for(int i=2; t>1; i++)
    {
        if(t%i==0)
        {
            while(t%i==0)
            {
                t/=i;
            }
            ans=ans-ans/i;
        }
    }
    cout<<ans<<endl;
}
int main()
{
    while(cin>>n)
    {
        if(n==0)break;
        n--;
        cal();
    }
    return 0;
}
POJ 2478 Farey Sequence(打表)

POJ 2478题目链接

数据范围太大,先打表统计欧拉数。

#include <iostream>
#include<cstdio>
using namespace std;
#include<cstring>
#define maxn 1000006
#define ll __int64
int x;
ll phi[maxn];
void init()
{
    for(int i=2;i<=maxn;i++)
    {
        if (!phi[i])
        {
            for (int j=i;j<=maxn;j+=i)
            {
                if (!phi[j])
                    phi[j]=j ;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}
int main()
{
    memset(phi,0,sizeof(phi));
    init();
    while(cin>>x)
    {
        if(x==0)break;
        ll ans=0;
        for(int i=1; i<=x; i++)
            ans+=phi[i];
        cout<<ans<<endl;
    }
    return 0;
}
POJ 3090 Visible Lattice Points

POJ 3090题目链接

该题主要求从原点看可以看到几个点,覆盖到的忽略掉。
主要是统计斜率,求斜率(0,1)开区间为基准进行求解,最后结果*2+3;
与2478相类似,每次增加的都是该值的素因子个数,如5*5,增加了1/5,2/5,3/5,4/5;6*6会增加1/6,5/6。

#include <iostream>
#include<cstdio>
using namespace std;
#include<cstring>
#define maxn 1000006
#define ll __int64
int x;
ll ans[maxn];
ll phi[maxn];
void init()
{
    for(int i=2; i<=maxn; i++)
    {
        if (!phi[i])
        {
            for (int j=i; j<=maxn; j+=i)
            {
                if (!phi[j])
                    phi[j]=j ;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
    for(int i=2; i<=maxn; i++)
        ans[i]=ans[i-1]+2*phi[i];
}
int main()
{
    memset(phi,0,sizeof(phi));
    memset(ans,0,sizeof(ans));
    init();
    int T;
    cin>>T;
    for(int num=1; num<=T; num++)
    {
        cin>>x;
        cout<<num<<" "<<x<<" "<<ans[x]+3<<endl;  //+3分别为+斜率=1,斜率=0,斜率=∞
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值