zoukankan      html  css  js  c++  java
  • [数论] 欧拉函数

    参考资料 : 欧拉函数及欧拉线性筛 - 辞树 - CSDN博客

    欧拉(Eular)函数 $varphi $

    欧拉函数是小于n的正整数中与n互质的数的数目((varphi(1)=1)

    (互质:两数有且仅有公因数 $ 1 $)

    $ $

    $ $

    欧拉函数 (varphi) 的性质

    1. 若(n)为质数,(varphi(n) = n-1)

    2. 对于 (n = p^{k}) ,有 (varphi(n) = (p-1)* p^{k-1})

    3. 欧拉函数是积性函数,若(gcd(n,m)=1),即(n)(m)互质,有(varphi(n*m) = varphi(n)*varphi(m))

    4. (n = sum_{i=1} ^{m} p_{i} ^{q_{i}}) ,则(varphi (n) = n * prod _{i=1} ^{m} (i - frac{1}{p_{i}}))

    5. 欧拉定理:对于互质的(a)(m)(a^{varphi(m)} equiv 1 (mod) (m))

    6.小于(n)且与(n)互质的数的和:(S = frac {n * varphi(n)}{2})

    7. 对于质数(p),若(n) (mod) (p=0),则(varphi(n*p) = varphi(n) * p) ;若(n) (mod) (p eq 0),则 (varphi(n*p) = varphi(n) *(p-1))

    8. 若(sum_{d|n}varphi(d) = n),则 (varphi(n) = sum_{d|n} mu(d) * frac{n}{d})

    显然后面几条我们用不上....反正先写着咯


    于是有了欧拉筛求素数顺便(雾)求欧拉函数值的代码

    void getprime(int lim)
    {
        nop[1]=1,phi[1]=0;
        for(int i=2;i<=lim;i++)
        {
            if(!nop[i])pri[++size]=i,phi[i]=i-1;
            for(int j=1;j<=size&&i*pri[j]<=lim;j++)
            {
                nop[i*pri[j]]=1;
                if(i%pri[j]==0)
                {
                    phi[i*pri[j]]=phi[i]*pri[j];
                    break;
                }
                else phi[i*pri[j]]=phi[i]*(pri[j]-1);
            }
        }
    }
    

    说说几道题吧

    [HAOI2012]外星人

    题面:

    艾莉欧在她的被子上发现了一个数字 N ,她觉得只要找出最小的 (x) 使得(varphi^{x}(N) =1)
    。根据这个 $x $她就能找到曾经绑架她的外星人的线索了。当然,她是不会去
    算,请你帮助她算出最小的 (x)

    输入:

               第一行一个正整数$ test$,接下来 $test$ 组数据每组数据第一行一个正整数$ m $,接下来
    

    $m $行每行两个正整数 $q_{i} $ 和 (p_{i})

               其中$prod_{i=1}^{m}p_{i}^{q_{i}}$为 $N$ 的标准分解形式。
    
    1
    2
    2 2
    3 1
    

    输出:

             每行一个整数$ans$
    
    3
    

    样例解释:

    (N=12 , varphi(12)=4,varphi(4)=2,varphi(2)=1),所以答案是3.

    (varphi(prod_{i=1}^{m}p_{i}^{q_{i}})=prod_{i=1}^{m}(p_{i}-1)p_{i}^{q_{i}-1})

    分析:

         其实题目求的是使得$varphi( varphi... (varphi (N)))=1$中$varphi$操作的个数
    

    通过打表 可以发现,只有(varphi(1))(varphi(2))的值为1,所以在最后一步前必然要把(N)转化为2(因为不能转为1啊,转1就两种方式),那么根据题目所提示之公式,因为每次出现了 (q_{i}-1),则必然会变少一个因子2(幂数变小),求出2的个数即可。但要注意若刚开始没有因子2则要多一步

          phi[i]表示i含有几个2,即要几次变成1
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+6;
    int phi[N],prime[N];
    bool isprime[N];
    int T,m,p,q,cnt;
    void Prime(){
    	memset(prime,0,sizeof(prime));
    	memset(isprime,false,sizeof(isprime));
    	isprime[0]=isprime[1]=true;
    	phi[1]=1;
    	for(int i=1;i<=N;++i){
    		if(!isprime[i]){
    			prime[++cnt]=i;
    			phi[i]=phi[i-1];
    		}
    		for(int j=1;j<=cnt&&prime[j]*i<=N;++j){
    			isprime[prime[j]*i]=true;
    			phi[i*prime[j]]=phi[i]+phi[prime[j]];
    			if(!(i%prime[j])) break;
    		}
    	}
    }
    int main(){
    	freopen("alien.in","r",stdin);
    	freopen("alien.out","w",stdout);
    	
    	Prime();
    	scanf("%d",&T);
    	while(T--){
    		int ans=0;
    		bool f=false;
    		scanf("%d",&m);
    		for(int i=1;i<=m;++i){
    			scanf("%d%d",&p,&q);
    			if(p==2)f=true;
    			ans+=phi[p]*q;
    		}
    		printf("%d
    ",ans+(f?0:1));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    05 DDMS中logcat的使用
    04项目的目录结构分析与资源引用
    03 Android之我的第一个.hello world 程序
    关于myeclipse的有关操作
    jsp运行原理分析
    JSP简介
    prepareStatement与Statement的区别
    正则表达式
    过滤器的作用和用法
    剑指Offer--数值的整数次方
  • 原文地址:https://www.cnblogs.com/lsy263/p/11266481.html
Copyright © 2011-2022 走看看