Rereading "challenge programming competition" -- fledgling

Posted by askbapi on Sat, 19 Feb 2022 06:37:27 +0100

In the final analysis, there are several simple number theory problems:

  1. Prime number problem (judgment, sieve method, decomposition, several common conclusions of decomposition) and divisor problem
  2. Fast power, matrix fast power
  3. gcd, exgcd (system of Congruence Equations) Euler function
  4. Inverse element
  5. Higher mathematics related: Gauss elimination and combinatorial number problems

Other more complex mathematical problems will be discussed when reading the advanced chapter
The explanation part refers to the advanced guide to algorithm competition and the course of acwing.

Determination of prime number

Try division, as long as you divide to the root sign N, because the multiplication of two numbers is equal to N, one must be greater than or equal to the root sign N and the other less than or equal to the root sign n.

bool is_prime(int x)
{
    if(x<2)
        return false; 
    for(int i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
            return false;
    }
    return true;
}

Ehrlich sieve method

As a result, I always push a vector and do subsequent processing.

bool primes(int x)
{
    for(int i=2;i<=x;i++)
    {
        if(v[i])
            continue;
        prime.push_back(i);
        for(int j=i;j<=x/i;j++)
            v[i*j]=1;
    }
}

If the prime number is screened from [a,b), the prime factor must not exceed sqrt (b). In [2,sqrt(b)), cross out the multiple of the screened prime number from [a,b).

Prime factor decomposition

Any number N greater than 1 can be decomposed into:

leetcode has done a question in the weekly competition, asking how many numbers can be obtained by multiplying different homogeneous factors. It's c1+c2 +... + cn
I am used to putting the decomposition results into a pair array for subsequent processing.

void divide(int x)
{
    for(int i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            int cnt=0;
            while(x%i==0)
            {
                x/=i;
                cnt++;
            }
            v.push_back({i,cnt});
        }
    }
    if(x>1)
    {
        v.push_back({x,1});
    }
}
}

Be careful not to leave out the case where x is prime.

Several prime and divisor formulas mentioned in the advanced Guide:

N! The number of medium quality factor p is:

Each divisor in N can be expressed as
Number of divisors:

The sum of all positive divisors is:

Counting

ll qmi(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=a*ans%mod;
        }
        a=a*a%mod;
        
        b>>=1;
    }
    return ans;
}

Matrix fast power

With the simplest piece of data, the larger Fibonacci explains:
f(n)=f(n-1)+f(n-2)
Combine f(n) and f(n-1) into a matrix form:

You can recurse through the nth power of this simple matrix.

When initializing, it is an identity matrix, and when multiplying, a function is used to realize matrix multiplication (the matrix is stored in a structure that records dimensions and contents):

struct matrix {
   int a[100][100];
   int n;
};
//Implementation of matrix multiplication
matrix matrix_mul(matrix A, matrix B, int mod) {
    matrix ret;
    ret.n = A.n;
    //Initialization result matrix
    for (int i = 0; i < ret.n; i++) {
        for (int j = 0; j < ret.n; j++){
            ret.a[i][j] = 0;
        }
    }
    //According to the definition of matrix multiplication, i and j are the positions of the number being calculated in the matrix. Since matrix multiplication is the addition of many numbers, k is used to enumerate the number of i rows multiplied by J columns
    for (int i = 0; i < ret.n; i++) {
        for (int j = 0; j < ret.n; j++) {
            for (int k = 0; k < A.n; k++) {
                ret.a[i][j] = (ret.a[i][j] + A.a[i][k] * B.a[k][j] % mod) % mod;
            }
        }
    }
    return ret;
}

//Initialize the identity matrix. It is equivalent to ans=1 in the fast power and ans=unit in the fast power of the matrix
matrix unit(int n)
{
    matrix ret;
    ret.n=n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i==j)
            {
                ret.a[i][j]=1;
            }
            else
            {
                ret.a[i][j]=0;
            }
        }
    }
    return ret;
}
matrix matrix_pow(matrix A,int p,int mod)
{
    matrix res=unit(A.n);
    for(;p;p/=2)
    {
        if(p&1)
        {
            res=matrix_mul(res,A,mod);
        }
        A=matrix_mul(A,A,mod);
    }
    return res;
}

In the following topics, if we use the fast power of matrix, the formula will be more difficult to deduce, so we should practice more.

gcd

int gcd(int a,int b)
{
    if(b)
        return gcd(b,a%b);
    return a;
}

exgcd

Don't worry about how it came from. The push formula should also adapt to recursion.

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int r=exgcd(b,a%b,x,y);
    int temp=y;
    y=x-(a/b)*y;
    x=temp;
    return r;
}

Application scenario of exgcd:
Find the solution of ax+by=c, give a,b,c and solve x, y
If c mod gcd(p,q)=0, the solution is: multiply the solution calculated by the previous algorithm by c/gcd(p,q), otherwise there is no integer solution.

If the minimum integer solution or all solutions are required
A solution (x1,y1) of ax+by=gcd(a,b) can be obtained by using the extended Euclidean algorithm:

Then the solution of ax+by=c is obtained as;

x=x1*c/gcd(a,b)

y=y1*c/gcd(a,b);

The title of the book

Number gcd of grid points on line segment
Lattice points like this can easily be combined with gcd or Euler functions
The visual representation of the topic is as follows:

So the answer is gcd (x,y) - 1. Minus 1 is because when i=gcd(x,y), it is an endpoint of the line segment and should not be included.

Double six exgcd
We have to see a formula
ax+by=1
First of all, there must be an integer pair (x, y) such that ax+by=gcd (a, b)
There is no solution when 1 is not gcd (a, b).
When 1 is gcd (a, b), use exgcd to solve (x, y)