The Common Content of Number Theory-Primes

In the process of doing the number thesis, the prime number appears frequently, and it is common in the basic and middle-level topics, even in many difficult questions. This blog will make a brief summary of the prime number and its use.

prime number

First of all, we should be clear about the definition of prime numbers:

Prime number, also known as prime number, has infinite numbers. A prime number is defined as a natural number larger than 1, in which there are no other approximations other than 1 and itself.

Estimation of the Number of Prime Numbers

Since there are infinite primes, how many primes are there in n?

The number of prime numbers below n can be estimated in the following way

Estimation of the Number of Prime Numbers: Pi(n)x/ln(n)

Sieve prime number

Knowing that there are so many primes, how can we get them?

Direct traversal judgment is obviously not advisable. In the competition, we usually use the method of primes to solve this problem. I don't know which senior person gave the name of sifting primes to the primes. I feel very appropriate. There are many sieving methods. Here I just introduce the Euler sieving method with the highest time efficiency. See the code.

const int MAXN = 10000000 + 10;
bool is_prime[MAXN];//Prime sieve, true denotes that the number is prime
int prime[MAXN];//A prime table in which all prime numbers within MAXN are stored
int tol;//Statistics of Prime Numbers

void PrimeTable(){
    //Initialization
    memset(is_prime,true,sizeof(is_prime));
    tol=0;
    //Start with the smallest prime number 2
    for(int i=2;i<MAXN;i++){
        //If it's a prime, add it to the list of prime numbers.
        if(is_prime[i]) prime[tol++]=i;
        //Screening prime number operation
        for(int j=0;j<tol;j++){
            if(i*prime[j]>MAXN)break;
            //Screen out the product of the current number and each number in the prime table (these cannot be prime because there are other factors)
            is_prime[i*prime[j]]=false;
            //Here's the key. It guarantees that each sum is screened only once (you can simulate this process on paper, and you will have a deep understanding).
            if(i%prime[j]==0)break;
        }
    }
}

The Application of Prime Number

Number of Screening Primes in Large Data Cells

The number of prime numbers in the sieving interval of the simulated sieving method is first tabulated and then screened according to the table.

typedef long long ll;

const int MAXN = 1000000+10;

bool is_prime[MAXN];//true is a composite number and false is a prime number.
int prime[MAXN/10];//Deposit prime number
bool num[MAXN];
int tol;
void find_prime(){
    memset(is_prime,false,sizeof(is_prime));
    tol=0;
    is_prime[1]=1;
    for(int i=2; i<MAXN; i++){
        if(!is_prime[i]){
            prime[tol++]=i;
            for(int j=i*2; j<MAXN; j+=i)
                is_prime[j]=1;
        }
    }
}

int main(){
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int T;
    cin>>T;
    find_prime();
    for(int cas=1; cas<=T; cas++){
        int a,b;
        scanf("%d %d",&a,&b);
        int n=b-a;
        memset(num,false,sizeof(num));
        for(int i=0;i<tol&&prime[i]*prime[i]<=b;i++){
            int j=0;
            if(a%prime[i]!=0)
                j=prime[i]-a%prime[i];//Find the first number (j+a)%prime[i]==0 that needs to be screened out
            if(a<=prime[i])
                j+=prime[i];//(j+a)/prime[i]==1, then (j+a) is a prime number, push down one
            for(;j<=n;j+=prime[i])
                num[j]=true;
        }
        int ans=0;
        for(int j=0;j<=n;j++){
            if(!num[j]) ans++;
        }
        if(a==1) ans--;
        printf("Case %d: %d\n",cas,ans);
    }
    return 0;
}

Prime factorization

There are two prime factorization methods

Firstly, the first naive decomposition method is suitable for Factorization when the number is small.

There are two different implementations, one of which you can choose.

int a[MAXN/10];//Preservation factor
int b[MAXN/10];//Number of preservation factors
int tol2;
void sbreak(ll n){
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    tol2=0;
    for(int i=0; prime[i]*prime[i]<=n&&i<tol; i++)//The tol here is the total number of prime sieved out.{
        if(n%prime[i]==0){
            a[tol2]=prime[i];
            while(n%prime[i]==0){
                b[tol2]++;
                n/=prime[i];
            }
            tol2++;
        }
    }
    if(n!=1){
        a[tol2]=n;
        b[tol2++]=1;
    }
}
const int M = 1000010;
int facs[M]; //All qualitative factors of n
int tot; //Number of prime factors of n
int kind; //Number of prime factor species
struct Factor{
    int val; //The value of the quality factor
    int num; //The number of prime factors
}factor[M];

void solve(int n){
    tot=0;
    for(int i=2;i*i<=n;i+=2){
        while(!(n%i))
            n/=i,facs[tot++]=i;
        if(i==2) --i;
    }
    if(n>1) facs[tot++]=n;
}

void collect(int n){
    solve(n);
    kind=0;
    factor[kind].val=facs[0];
    factor[kind].num=1;
    kind++;
    for(int i=1;i<tot;i++){
        if(facs[i]!=facs[i-1]){
            factor[kind].val=facs[i];
            factor[kind].num=1;
            kind++;
        }
        else{
            factor[kind-1].num++;
        }
    }
}

The second is Pollard_rho factorization, which is suitable for Factorization with large numbers.

This method of prime decomposition involves the knowledge of Miller Rabin prime number test. You can go to other articles on the Internet to learn about it. It doesn't matter if you are in trouble. There are annotations in the code. You can also read the code to understand it directly.

#include <ctime>
#define LL long long
#define case 10//Generally 8-10 is enough.
using namespace std;

LL Get_rand(LL n){
    return 2 + rand()%(n-2);
}

LL Mul(LL a,LL b,LL m){
    LL ans = 0;
    while(b){
        if(b & 1){
            ans = (ans + a) % m;
            b--;
        }
        else{
            a = (2 * a) % m;
            b >>= 1;
        }
    }
    return ans%m;
}

LL Quick_mod(LL a,LL n,LL m){
    LL ans = 1;
    while(n){
        if(n & 1){
            ans = Mul(ans, a, m);
        }
        a = Mul(a, a, m);
        n >>= 1;
    }
    return ans;
}

bool Miller_Rabbin(LL n){
    if (n==2)return true;
    if (n<2||!(n&1))return false;
    int t=0;
    LL a,x,y,u=n-1;
    while((u&1)==0) t++,u>>=1;
    for(int i=0;i<case;i++){
        a=rand()%(n-1)+1;
        x=Quick_mod(a,u,n);
        for(int j=0;j<t;j++){
            y=Mul(x,x,n);
            if (y==1&&x!=1&&x!=n-1)
                return false;
            /// The theorem is used. If there is a nontrivial square root of 1 for module n, then n is a composite number.
            /// If a number x satisfies the equation x^2_1 (mod n), but x is not equal to two'trivial'square roots of 1 for module n: 1 or -1, then x is a non-trivial square root of 1 for module n.
            x=y;
        }
        if (x!=1)/// According to Fermat's small theorem, if n is a prime, there is a^(n-1)1(mod n). So n can't be a prime.
            return false;
    }
    return true;
}

long long factor[1000];//The result of prime factor decomposition (disordered when returned)
int tol;//Number of prime factors. Array scalars start at 0

long long gcd(long long a,long long b){
    if(a==0)return 1;//???????
    if(a<0) return gcd(-a,b);
    while(b){
        long long t=a%b;
        a=b;
        b=t;
    }
    return a;
}

long long Pollard_rho(long long x,long long c){
    long long i=1,k=2;
    long long x0=rand()%x;
    long long y=x0;
    while(1){
        i++;
        x0=(Mul(x0,x0,x)+c)%x;
        long long d=gcd(y-x0,x);
        if(d!=1&&d!=x) return d;
        if(y==x0) return x;
        if(i==k){y=x0;k+=k;}
    }
}
//Prime factorization of n
void findfac(long long n){
    if(Miller_Rabbin(n))//Prime number{
        factor[tol++]=n;
        return;
    }
    long long p=n;
    while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    findfac(p);
    findfac(n/p);
}

int main(){
    int t;
    LL n;
    srand(time(NULL));
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&n);
        if(Miller_Rabbin(n))
            cout<<"Prime"<<endl;
        else{
            tol = 0;
            findfac(n);
            LL minn = 99999999999999999;
            for(int i=0; i<tol; i++)
                minn = min(minn,factor[i]);
            cout<<minn<<endl;
        }
    }
    return 0;
}

Find the number of factors of n (a factor, not a prime factor)

The prime factor decomposition of n yields p1^a1+p2^a2 +... +pi^ai
 Then the number of factors is: (a1+1)*(a2+1)*... + (ai+1)

These are the common applications of prime numbers. You are welcome to leave a message to supplement them.

Posted by Bubbagump on Wed, 03 Jul 2019 13:01:08 -0700