uva 10006 Introduction to Number Theory

This is an introductory number theory topic, only need to find prime numbers and fast power modulus

Question: Enter a number n. If the number is non-prime, ask whether all the numbers in the interval 2 ~ n-1 are satisfied \begin{displaymath}a^n \bmod n = a\end{displaymath}?


Solution: Because the amount of data is not large, it can be solved violently directly


Solution 1: Brute force solution

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;

long long prime[65010];
long long n;


void init()
{
    memset(prime , 0 , sizeof(prime));
    long long i , j;

    for(i = 2; i < 65000 ; i++)
    {
        if(prime[i] == 0)
        {
            for(j = i+i; j < 65000; j += i)
                prime[j] = 1;
        }
    }
}

long long pow_mod(long long a)
{
    long long x = 1 , y = a;
    long long z = n;
    while(z-1)
    {
        if(z%2 == 1)
            x = x*y%n;
        y = y*y%n;
        z /= 2;
    }
    x = x*y%n;
    return x;
}

int main()
{
    init();
    while(1)
    {
        long long i ;
        cin>>n;
        if(n == 0)  break;
        if(!prime[n])
        {
            cout<<n<<" is normal."<<endl;
            continue;
        }
        for(i = 2; i < n; i++)
            if(pow_mod(i) != i)  break;

        if(i == n)
            cout<<"The number "<<n<<" is a Carmichael number."<<endl;
        else cout<<n<<" is normal."<<endl;
    }
    return 0;
}

Solution 2:

Using the unique decomposition theorem, any non-prime number will be composed of prime factors, so when we ask for a ^ n,

We pass a = x * y, a ^ n = (x ^ n) * (y ^ n), then we only need a factor of a, which can reduce the time complexity

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;

int prime[65010];
long long n;
long long gcd[65010];
long long pri[65010];

void init()
{
    memset(prime , 0 , sizeof(prime));
    long long i , j;

    for(i = 2; i < 65000 ; i++)
    {
        if(prime[i] == 0)
        {
            for(j = i+i; j < 65000; j += i)
                prime[j] = 1 , pri[j] = i;
        }
    }
}

long long pow_mod(long long a)
{
    long long x = 1 , y = a;
    long long z = n;
    while(z-1)
    {

        if(z%2 == 1)
            x = x*y%n;
        y = y*y%n;
        z /= 2;
    }
    x = x*y%n;
    return x;
}

int main()
{
    init();
    while(1)
    {
        long long i , j , x;
        cin>>n;
        if(n == 0)  break;
        if(!prime[n])
        {
            cout<<n<<" is normal."<<endl;
            continue;
        }
        if((gcd[2] = pow_mod(2)) != 2)
        {
            cout<<n<<" is normal."<<endl;
            continue;
        }
        if((gcd[3] = pow_mod(3)) != 3)
        {
            cout<<n<<" is normal."<<endl;
            continue;
        }
        for(i = 4; i < n; i++)
        {
            if(prime[i])
            {
                j = i/pri[i];
                x = gcd[pri[i]]*gcd[j]%n;
                if((gcd[i] = x) != i)  break;
            }
            else
            {
                gcd[i] = pow_mod(i);
                if(gcd[i] != i)  break;
            }
        }


        if(i == n)
            cout<<"The number "<<n<<" is a Carmichael number."<<endl;
        else cout<<n<<" is normal."<<endl;
    }
    return 0;
}


Published 190 original articles · 19 praises · 200,000+ views

Guess you like

Origin blog.csdn.net/zengchenacmer/article/details/30798045