hdu 1395 2^x mod n = 1 violent Euler function

Keywords: PHP less

Topic link: http://acm.hdu.edu.cn/showproblem.php?pid=1395

 

Problem description

Given a number n, find the minimum x (x > 0) that satisfies 2 ^ x mod n = 1.

input

A positive integer for each line, the value of n.

yield

If there is a minimum x, print a line of 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

 

 

When you don't know anything about violence, cycle 1 W or not to find out to illustrate that there is no more, the greater the number of cycles, the less easy WA

#include<iostream>
#include<cstdio>
using namespace std;

typedef long long ll;

int main(){//2^x mod n = 1
    ll n;
    while(~scanf("%lld",&n)){
        if(n<=2)
            printf("2^? mod %d = 1\n",n);
        else{
            int x=2;
            int ans=1;
            while(x%n!=1 && ans<=10000){
                x=2*x%n;
                ans++;
            }
            if(ans>=10000)
                printf("2^? mod %d = 1\n",n);
            else
                printf("2^%d mod %d = 1\n",ans,n);
        }

    }

	return 0;
}

 

When we know the point deduction, we find that n is not a multiple of 2.

#include<iostream>
#include<cstdio>
using namespace std;

typedef long long ll;

int main(){//2^x mod n = 1
    ll n;
    while(~scanf("%lld",&n)){
        if(n<=2 || n%2==0)
            printf("2^? mod %d = 1\n",n);
        else{
            int x=2;
            int ans=1;
            while(x%n!=1){
                x=2*x%n;
                ans++;
            }

            printf("2^%d mod %d = 1\n",ans,n);
        }

    }

	return 0;
}

 

Euler

Theorem:

 

Let gcd(a,m)=1, there must be a positive integer x, so that a^x=1(mod m), and let the smallest positive integer satisfying the equation be x0, it must satisfy x0|phi (m). Note that M > 1.

Otherwise, if gcd(a,m)!=1, the equation a^x=1(mod m) has no solution.

 

Typical Topics: HDU1395, HDU3307, POJ3696

 

According to the above theorem, we need to find phi(n) first.

 

 

When a and n are not mutually prime, they certainly do not exist. Otherwise, the maximum value of x is the Euler function of x. Therefore, it is necessary to screen the factors of the Euler function of x. Considering the data range of this problem, Euler function is directly obtained, and gcd is binary.

 

The minimum positive integer x satisfying a^x 1(mod n) is called the order of a modulus n.

Now we give two positive integers and find x.

 

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cmath>
using namespace std;
#define SIZE 655
//Screening Method for Euler Function
int Euler[SIZE] = {0};
void sieve(){
    Euler[1] = 1;
    for(int i=2;i<SIZE;++i){
        if ( Euler[i] ) continue;
 
        for(int j=i;j<SIZE;j+=i){
            if ( !Euler[j] ) Euler[j] = j;
 
            Euler[j] = Euler[j] / i * ( i - 1 );
        }
    }
}
typedef int int_t;
int_t gcd(int_t a,int_t b){
    while( b ){
        int_t r = b;
        b = a % b;
        a = r;
    }
    return a;
}
//Fast GCD
int Fastgcd(int a, int b)
{
    if (a == 0) return b;
    if (b == 0) return a;
    if (!(a & 1) && !(b & 1))
        return Fastgcd(a>>1, b>>1)<<1;
    else if (!(b & 1))
    return Fastgcd(a, b>>1);
    else if (!(a & 1)) return Fastgcd(a>>1, b);
    else return Fastgcd(abs(a - b), min(a, b));
}
int euler_phi(int n)
{
    int m = floor(sqrt(n+0.5));
    int ans = n;
    for(int i = 2; i <= m; 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;
}
//Calculate a^b%mod
typedef long long llt;
llt powerMod(llt a,llt b,llt mod){
    llt ret = 1LL;
    a %= mod;
    while( b ){
        if ( b & 1LL ) ret = ret*a % mod,--b;//multiMod(ret,a,mod),--b;
        b >>= 1LL;
        a = a*a%mod;//multiMod(a,a,mod);
    }
    return ret;
}
 
int main(){
    //sieve();
    int k;scanf("%d",&k);
    while(k--){
        int a,n;
        scanf("%d%d",&a,&n);
        if ( Fastgcd(a,n) == 1){
            //printf("%d\n",Euler[n]);
            int tmp = euler_phi(n);
            int ans = INT_MAX;
            for (int i = 1;i*i <= tmp;++i){
                if ( tmp % i  ) continue;
                if (1 == powerMod( a,i,n) ) ans = min(ans,i);
                if (1 == powerMod( a,tmp/i,n)) ans = min(ans,tmp/i);
            }
            printf("%d\n",ans);
        }
        else
            printf("-1\n");
    }
    return 0;
}

Posted by JNorman on Wed, 17 Apr 2019 19:09:33 -0700