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 .
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,找到满足的最小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互质,则
- 
当n=1时,明显不成立,所以找不到最小的x。
 - 
当n为偶数时,是偶数,一个偶数模另外一个偶数,明显也不成立,所以找不到最小的x。
 - 
当n为非1的奇数时,n和2互质,由欧拉定理,令a=2,n为输入的奇数,则根据欧拉函数计算得φ(n),代入欧拉定理得,即。
对比题目要求的,很容易发现φ(n)必是符合要求的x。
但φ(n)未必是最小的x,所以就可以从1~φ(n)遍历,找到符合题目 最小的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;
    }
}
            
                    
                
                
            
        
浙公网安备 33010602011771号