• 拓展欧拉定理浅谈


    前置芝士——欧拉定理:

    若正整数(a,n)互质,则(a^{phi(n)}equiv1~(mod~n)),其中(phi(n))为欧拉函数

    证明:

    设小于(n)且与(n)互质的数构成的集合(即简化剩余系)为{(a_1,a_2,a_3...a_{phi(n)})},对于(forall a_i,a_j),若(a_i,a_j)在同一同余类时,有(~a imes a_iequiv~a imes a_j~(mod~n)),则(a imes(a_i-a_j)equiv~0~(mod~n)),又因为(a)(n)互质,所以(a_i-a_jequiv0),即(a_iequiv~a_i)。因此,当(a_i)(a_j)不在同一同余类时,(a!a_i,a!a_j) 也在不同的同余类。

    又因为简化剩余系关于模(n)乘法封闭,故(a!a_i,a!a_j)也在这个简化剩余系中。因此,集合{(a_1,a_2...a_{phi(n)})}和集合{({a!a_1,a!a_2...a!a_{phi(n)}})}都可以表示(n)的简化剩余系,因此:

    [a^{phi(n)}a_1a_2...a_{phi(n)}equiv(a!a_1)(a!a_2)...(a!a_{phi(n)})~(mod~n) ]

    [Rightarrow~a^{phi(n)}a_1a_2...a_{phi(n)}equiv~a_1a_2...a_{phi(n)}~(mod~n) ]

    [Rightarrow a^{phi(n)}equiv~1~(mod~n) ]

    证毕


    正题:拓展欧拉定理

    当我们求(a^b(mod~p))时,最常用的应该就是快速幂了吧?但,如果(ble10^{100})呢?如果(ble10^{20000000})呢(见模板)?

    这个时候,不仅(long~long)不够,快速幂也不够了。。

    所以,又一个神奇的定理出现了!

    它大概分以下三种情况

    [a^bequivleft{egin{aligned}a^{b\%phi(n)}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~gcd(a,n)=1\a^b~~~~~~~~~~~~~~~~~~~gcd(a,n) eq1&b<phi(n)\a^{b\%phi(n)+phi(n)}~~~~gcd(a,n) eq1&bgephi(n)end{aligned} ight. ]

    第一种情况:

    证明:

    (b=q imesphi(n)+r),其中(0le r<phi(n)),即(r=bmodphi(n))

    故:

    [a^bequiv a^{q imesphi(n)+r}equiv (a^{phi(n)})^q imes a^requiv1^q imes a^requiv a^{bmodphi(n)} ]

    证毕

    第二种情况:废话

    第三种情况:咕咕咕~~ (有能力的读者可以自己证明啦 (就是我不会)

    有一个公理说明:这东西你虽然不知道它怎么来的,但知道怎么用就行。


    OK,咱们来实践,上例题!

    例题:P4139 上帝与集合的正确用法

    一句话题意:(2^{2^{2...}}\%~p)

    都不需要怎么引入了,看到的第一眼就知道是个拓展欧拉定理,但问题是如何求(2^{2^{2...}}\%~phi(p)+phi(p))

    但你们观察这个式子(2^{2^{2...}}\%~phi(p)+phi(p)),把中间的(2^{2^{2...}}\%~phi(p))拿出来,把它看作一个整体,又变成了(2^{2^{2...}}\%~p).

    然后我们就可以递归直到(p)变为(0),再每次加回(phi(p)),就A了。

    所以先用线性筛预处理出所有的(phi(p)),然后递归,本题就完事了。。

    手起,码落

    #include<bits/stdc++.h>
    #define re register
    using namespace std;
    const int N=1e7+5;
    int E[N],T;
    void euler(int MAXN)  
    {  
    	E[1]=1;
        for(int i=2;i<=MAXN;i++)
    	{  
            if(!E[i])
            for(int j=i;j<=MAXN;j+=i)
    		{  
                if(!E[j])E[j]=j;
                E[j]=E[j]/i*(i-1);
            }  
        }  
    }
    inline int Pow(int x,int y,int mod)
    {
    	re int sum=1;
    	for(;y;y>>=1,x=(1ll*x*x)%mod)
    		if(y&1)sum=(1ll*sum*x)%mod;
    	return sum;
    }
    inline int print(int x)
    {
    	if(x==1)return 0;
    	return Pow(2,print(E[x])+E[x],x);
    }
    int main()
    {
    	re int p;
    	euler(N-5);
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d",&p);
    		printf("%d
    ",print(p));
    	}
    	return 0;
    }
    

    都看到这了,给个赞不!QWQ~

  • 相关阅读:
    android笔记5——同一个Activity中Fragment的切换
    JavaScript 刚開始学习的人应知的 24 条最佳实践
    位运算符之异或的化腐朽为奇妙
    unity常见问题之20题
    汉澳sinox不受openssl心血漏洞影响并分析修复其漏洞代码
    基于canvas和Web Audio的音频播放器
    poj2595(凸包)
    HDU 1257 最少拦截系统(dp)
    【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容
    万能狗! 程序猿屌丝独自创业之路(一)
  • 原文地址:https://www.cnblogs.com/jkzcr01-QAQ/p/13575203.html
Copyright © 2020-2023  润新知