zoukankan      html  css  js  c++  java
  • [扩展欧拉定理例题]降幂大法

    降幂大法1

    题面:

       给出a,b,p,计算a^b %p 的结果,0< a <= 10^9,0< b <= 10^10000,0< p <= 10^9。

    思路:

      10的10000次方,这题不简单。那么经过欧拉定理的学习之后,有如下结论:,其中a,n互质,但是很显然,他不能用来解决这道题。那么扩展欧拉定理应运而生了。

      acacmodφ(m)+φ(m)(mod m)

      其中c>=φ(m)。他很强,强到了一种逆天的程度。对于这个定理,我有一个优雅的证明,但是在网上打不出来。又及,c<φ(m)的时候直接快速幂。

      回到这道题,这道题无非就是用扩展欧拉定理去解决它,虽然它的p在后面很恶心。

      先把所有的东西读进来,处理好φ(p),再对指数进行类似于快读的处理。由于快读只涉及到加和乘,完全可以一边算一遍%φ(p)。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<fstream>
    using namespace std;
    #define ll long long
    ll a,b,p,mod;
    char s[100005];
    ll phi(int n){
        ll ans=n;
        for(int i=2;i*i<=n;++i){
            if(n%i==0){
                ans=ans/i*(i-1);
                while(n%i==0)n/=i;
            }
        }
        if(n>1)ans=ans/n*(n-1);
        return ans;
    }
    long long KSM(ll a,ll b){
        ll sp=1;
        while(b){
            if(b&1)sp*=a;
            sp%=p;
            b>>=1;
            a=a*a;
            a%=p;
        }
        return sp;
    }
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        scanf("%lld%s%lld",&a,s,&p);
        int len=strlen(s);
        mod=phi(p);
        int flag=0;
        for(int i=0;i<len;++i){
            b=b*10+(s[i]-'0');
            if(b>=mod)flag=1;
            b%=mod;
        }
        if(flag)b+=mod;
        cout<<KSM(a,b)%p<<endl;
        return 0;
    }
    View Code

    降幂大法2

    题面:

      P3787.png

    思路:

      禁止套娃!!是的,看到省略号的时候我就直接懵了。你管这个叫题?分明就是俄罗斯套娃。

      但是是套娃,又有答案,那他就不是无限套娃(世 界 崩 坏)。见过俄罗斯套娃的都知道,套娃必然会有一个最小的,此题个关键就在于找出最小的套娃。

      由扩展欧拉定理可以知道,一个数膜另外一个数,这个任务可以甩给他的指数。指数又甩给它的指数,这就是套娃。于是这样我们可以设计一个函数,先令T=22...他的任务是解决T%p的问题,于是无限递归处理,然后p在不断地phi,phi,phi,phi...直到φ(p)=1,那么很显然的,一个数%1=0.套娃结束。最小的娃找到了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<fstream>
    using namespace std;
    #define ll long long
    ll a,b,p;
    char s[100005];
    ll phi(int n){
        ll ans=n;
        for(int i=2;i*i<=n;++i){
            if(n%i==0){
                ans=ans/i*(i-1);
                while(n%i==0)n/=i;
            }
        }
        if(n>1)ans=ans/n*(n-1);
        return ans;
    }
    long long KSM(ll a,ll b,ll mod){
        ll sp=1;
        while(b){
            if(b&1)sp*=a;
            sp%=mod;
            b>>=1;
            a=a*a;
            a%=mod;
        }
        return sp;
    }
    int solve(int p){
        int k=phi(p);
        if(k==1)return 0;
        return KSM(2,(solve(k)+k),p);
    }
    int main(){
        while(scanf("%lld",&p)!=EOF){
            cout<<solve(p)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    python实现单链表及常用方法->判空|长度|头尾及指定插入|删除|搜索|反转
    k8s v1.21.9集群安装带认证的elk 6.8.18
    docker安装Elasticsearch6.8集群并设置密码
    kubernetes v1.20.9部署keepalived-vip实现高可用pod访问
    rsync远程同步工具的使用-实现跳板机与内网数据传输
    旧金山大学 大卫 算法演示
    IO多路复用之select、poll、epoll详解-转载
    docker容器中使用systemctl命令 set-hostname
    win7 安装ss
    常用相似度语料
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12076852.html
Copyright © 2011-2022 走看看