hdu1395 2^x mod n = 1

题意是给定一个 n n ,问是否存在一个 x x 使得 2 x   m o d   n = 1 2^x \ mod \ n = 1
思路:首先如果n为偶数的时候肯定不存在解,所以如果存在解的话, ( 2 , n ) = 1 (2,n)=1 ,一个比较好的思路是,由于由于2是原根,所以这个题目就是求2 模 n的阶,根据原根的性质,我们只需要在φ(n)的因子中用快速幂找到最小的x就可以了。
A C   C o d e : AC \ Code:

//#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<map>
#define ll long long
using namespace std;
int phi(int n){
    int ans = n;
    for(int i = 2;i <= sqrt(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;
}
ll Qpow(ll a,ll b,ll p){
    ll ans = 1;
    a %= p;
    while(b){
        if(b & 1) ans = ans * a %p;
        b >>= 1;
        a = a * a %p;   
    }
    return ans;
}
int main(){
    int p;
    while(cin>>p){
        if(p == 1 || p % 2 == 0) {printf("2^? mod %d = 1\n",p);continue;}
        int a = phi(p);
        ll ans = (ll)1e10;
        if(Qpow(2,a,p) == 1) ans = a;
        for(int i = 2;i <= sqrt(a);++i){
            if(a % i == 0) {
                if(Qpow(2,i,p) == 1){ans = min(ans,(ll)i);}
                if(Qpow(2,a/i,p) == 1) {ans = min(ans,(ll)a/i);}
            }
        }
        if(ans == (ll)1e10) printf("2^? mod %d = 1\n",p);
        else printf("2^%d mod %d = 1\n",ans,p);
        
    }

}
发布了632 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/103965600
今日推荐