zoukankan      html  css  js  c++  java
  • hdu 1395 2^x(mod n) = 1(C++)(欧拉定理 分解素因数)

    hdu 1395 2^x(mod n) = 1

    点击做题网站链接

    题目描述

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

    Problem Description
    Give a number n, find the minimum x(x>0) that satisfies 2x(mod n)=12^x(modspace 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

    中文翻译

    Problem Description
    给出一个数字n,找到满足2x(mod n)=12^x(modspace n) = 1的最小x(x> 0)。

    Input
    每行一个正整数,n的值。

    Output
    如果存在最小x,则打印一条2^x mod n = 1的行。
    否则,打印2^?mod n = 1。
    您应该用特定数字替换x和n。

    Sample Input
    2
    5

    Sample Output
    2^? mod 2 = 1
    2^4 mod 5 = 1

    解题思路

    先贴出欧拉定理:
    若n,a为正整数,且n,a互质,则aφ(n)1(mod n)a^{φ(n)} ≡ 1 (modspace n)

    1. 当n=1时,明显2x(mod 1)=12^x(modspace 1) = 1不成立,所以找不到最小的x。

    2. 当n为偶数时,2x2^x是偶数,一个偶数模另外一个偶数,明显2x(mod n)=12^x(modspace n) = 1也不成立,所以找不到最小的x。

    3. 当n为非1的奇数时,n和2互质,由欧拉定理,令a=2,n为输入的奇数,则根据欧拉函数计算得φ(n),代入欧拉定理得2φ(n)1(mod n)2^{φ(n)} ≡ 1 (modspace n),即2φ(n)(mod n)=12^{φ(n)} (modspace n) = 1
      对比题目要求的2x(mod n)=12^x(modspace n) = 1,很容易发现φ(n)必是符合要求的x。
      但φ(n)未必是最小的x,所以就可以从1~φ(n)遍历,找到符合题目2x(mod n)=12^x (modspace n) = 1 最小的x。

    注意:计算2^x mod n时用快速幂乘,否则不但慢还容易爆。

    问题解答

    #include <iostream>
    #define LL long long
    using namespace std;
    
    int oula(int n)//计算n的欧拉函数
    {
        int rea=n;
        for(int i=2; i*i<=n; i++)
            if(n%i==0)//第一次找到的必为素因子
            {
                rea=rea-rea/i;
                do
                    n/=i;//把该素因子全部约掉
                while(n%i==0);
            }
        if(n>1)
            rea=rea-rea/n;
        return rea;
    }
    
    LL ksm(LL a,LL b,LL mod)//快速幂计算2^b%mod
    {
        LL ans = 1;
        a %= mod;
        while( b>0 )
        {
            if( b&1 ) ans = (ans*2)%mod;
            b >>= 1;//位运算,右移1位,相当于除以2
            a = (a*a)%mod;
        }
        return ans;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
        int n,x;
        bool flag;
        while( cin>>n )
        {
            flag = 0;
            if( (n&1) && (n!=1) )//当n为非1的奇数时
            {
                flag = 1;
                int phi = oula(n);
                cout << phi << endl;
                for(x=1;x<phi;++x)
                    if(ksm(2,x,n)==1)//如果找到符合题意的
                        break;
            }
            if(flag)
                cout << "2^" << x << " mod " << n << " = 1" << endl;
            else
                cout << "2^? mod " << n << " = 1" << endl;
        }
    }
    
    
  • 相关阅读:
    leetCode 移动零 问题记录
    leetCode 加一 问题记录
    leetCode 两个数组的交集 II 问题记录
    leetCode 只出现一次的数字 问题记录
    leetCode 旋转数组 问题记录
    将本地项目上传到git
    RabbitMQ Linux 安装教程
    springboot RabbitMQ 配置
    linux——mysql5.5 安装遇到问题总结&解决方式
    Js预编译 GO和AO活动对象
  • 原文地址:https://www.cnblogs.com/yuzilan/p/10626066.html
Copyright © 2011-2022 走看看