• hdu 1395 2^x mod n = 1(欧拉函数)


    2^x mod n = 1

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 18742    Accepted Submission(s): 5860

    Problem Description
    Give a number n, find the minimum x(x>0) that satisfies 2^x mod n = 1.
     
    Input
    One positive integer on each line, the value of n.
     
    Output
    If the minimum x exists, print a line with 2^x mod n = 1.

    Print 2^? mod n = 1 otherwise.

    You should replace x and n with specific numbers.
     
    Sample Input
    2 5
     
    Sample Output
    2^? mod 2 = 1 2^4 mod 5 = 1
     

    题意:求一个最小的正整数x让2^x mod n = 1.

    思路:如果gcd(2,n)!=-1或者n==1的时候显然无解

    否则可以用欧拉函数解

    欧拉定理:

    设gcd(a,m)=1,必有正整数x,使得a^x=1(mod m),且设满足等式的最小正整数为x0,必满足x0|phi(m).注意m>1.

    否则如果gcd(a,m)!=1,则方程a^x=1(mod m)没有解。

     

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define LL long long
    LL e[1000008],t;
    LL pow_mod(LL a,LL n,LL mod)
    {
        LL ans=1;
        while(n)
        {
            if(n&1) ans=ans*a%mod;
            a=a*a%mod;
            n>>=1;
        }
        return ans;
    }
    LL gcd(LL a,LL b)
    {
        return b?gcd(b,a%b):a;
    }
    LL euler_phi(LL n)//欧拉函数
    {
        LL m=sqrt(n+0.5);
        LL ans=n,i;
        for(i=2; i<=m; i++)
        {
            if(n%i==0)
            {
                ans=ans/i*(i-1);
                while(n%i==0)n=n/i;
            }
        }
        if(n>1)ans=ans/n*(n-1);
        return ans;
    }
    void finds(LL n)
    {
        LL i;
        e[t++]=n;
    
        for(i=2; i*i<=n; i++)
        {
            if(n%i==0)
            {
                if(i*i==n)
                    e[t++]=i;
                else
                {
                    e[t++]=i;
                    e[t++]=n/i;
                }
            }
        }
    }
    int main()
    {
        int T;
        LL a,n;
        while(~scanf("%lld",&n))
        {
            if(n%2==0||n==1)
            {
                printf("2^? mod %lld = 1
    ",n);
                continue;
            }
            LL m=euler_phi(n);
            t=0;
            finds(m);
            sort(e,e+t);
            LL ans;
            for(int i=0; i<t; i++)
            {
                if(pow_mod(2,e[i],n)==1)
                {
                    ans=e[i];
                    break;
                }
            }
            printf("2^%lld mod %lld = 1
    ",ans,n);
        }
        return 0;
    }

     

     

  • 相关阅读:
    利用线程池爬虫
    多任务协程怎么写
    利用协程多任务协程爬取前几页投诉网
    cookie的处理和代理池的建立
    bs4和xpath的用法
    怎么使用Ip代理词
    雪球网新闻标题的爬取
    爬虫学习的基础篇
    小说文本爬取
    24 张图彻底弄懂九大常见数据结构
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/9087667.html
Copyright © 2020-2023  润新知