zoukankan      html  css  js  c++  java
  • 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;
    }

     

     

  • 相关阅读:
    系统设计5:Google三剑客
    lintcode亚麻九题
    设计模式17:单例模式
    设计模式16:迭代器模式
    设计模式15:组合模式
    476. Number Complement
    561. Array Partition I
    627. Swap Salary
    617. Merge Two Binary Trees
    728. Self Dividing Numbers
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/9087667.html
Copyright © 2011-2022 走看看