【Number Theory】| Find the divisor, find the number of divisors, find the sum of divisors, the greatest common divisor, the least common multiple

1. Try to divide

#include <iostream>
#include <vector>
#include <algorithm>
#define read(x) scanf("%d",&x)

using namespace std;

vector<int> getDivisors(int x)
{
    
    
    vector<int> res;
    for (int i=1;i<=x/i;i++) {
    
    
        if (x%i==0) {
    
    
            res.push_back(i);
            if (i!=x/i) res.push_back(x/i);
        }
    }
    sort(res.begin(),res.end());
    return res;
}

int main()
{
    
    
    int n,x;
    read(n);
    while (n--) {
    
    
        read(x);
        vector<int> res=getDivisors(x);
        for (int t:res) printf("%d ",t); //仅适用于Stl容器的遍历
        puts("");
    }
    return 0;
}

Suppose the prime factor decomposition of N, N=p1 a1 ×p2 a2 ×p3 a3 ×……×pn an , p1 to pn are all prime numbers.

Then the number of divisors of N num=(a1+1)×(a2+1)×(a3+1)×……×(an+1)

​ The sum of divisors of N sum=(p1 0 +p1 1 +p1 2 +……×p1 a1 )×(p2 0 +p2 1 +p2 2 +……×p2 a2 )×……× (pn 0 + pn 1 +pn 2 +……×pn an )

Therefore, questions 2 and 3 both involve the part of decomposing prime factors in the previous prime numbers.

2. Find the number of rounds

Modulo

Addition:(a+b+c)%p == a%p + b%p + c%p To be safe, if the range of a%p + b%p + c%p exceeds p, write it as(a%p + b%p + c%p) % p

Multiplication:,(a×b×c)%p == a%p × b%p × c%p also in order to prevent the value from exceeding p, write:(a%p × b%p × c%p)%p

Here N=a1×a2×……an, so the decomposed prime factor of each ai is calculated, and it cannot be stored in the array. The subscript is the prime factor, and the value is the number of the prime factor, because the numerical range is too large, 2e9, even if the array is opened in the main function, it cannot be opened less than 1e9, 1e8 can be opened, so it is better to use hash mapping here, and use the map container directly.

#include <iostream>
#include <unordered_map>
#define read(x) scanf("%d",&x)
#define ff first
#define ss second

using namespace std;

const int mod=1e9+7;

int main()
{
    
    
    int n,x;
    read(n);
    unordered_map<int,int> hash;
    while (n--) {
    
    
        read(x);
        //对x分解质因数,存在hash表中
        for (int i=2;i<=x/i;i++) 
            while (x%i==0) x/=i,hash[i]++;
        if (x>1) hash[x]++;
    }
     //开始求个数,注意map容器的遍历方法
    long long res=1;
    for (auto t:hash) res=(res*(t.ss+1))%mod;
    printf("%d\n",res);
    return 0;
}

3. Find the sum of the approximate numbers

Seeking P = T 0 + P . 1 + P 2 + P × ...... A simple algorithm:

p 3 +p 2 +p+1 can be written as p * (p 2 +p+1)+1, it can be written as p * ((p * (p+1)) +1) +1, according to this idea,

Initialize t=1;

while(a--) t=t*p+1;

t=1, which is p 0 =1

then,

① t * p+1=p0 * p+1=p+1

② t * p+1=(p+1) * p +1 = p2+p+1

③ t * p+1=(p2+p+1) * p+1=p3+p2+p+1

#include <iostream>
#include <unordered_map>
#define read(x) scanf("%d",&x)
#define ff first
#define ss second

using namespace std;

const int mod=1e9+7;

int main()
{
    
    
    int n,x;
    read(n);
    unordered_map<int,int> hash;
    while (n--) {
    
     //把n个数都分解质因数,累积起来了,相当于N本身了
        read(x);
        for (int i=2;i<=x/i;i++) 
            while (x%i==0) hash[i]++,x/=i;
        if (x>1) hash[x]++;    
    }
    
    long long res=1;
    for (auto prime:hash) {
    
    
        int p=prime.ff,a=prime.ss;
        long long t= 1;
        while (a--) t=(t*p+1)%mod;
        res=(res*t)%mod;
    }
    printf("%d",res);
    return 0;
}

Is the modulo question on line 27 confusing?

Written as, t=t*p+1;without taking the modulus, it is wrong.

4. Greatest common divisor

d can divide a, denoted as d|a, that is, a=k×d.

Derivation:

Find the greatest common factor of a and b, namely d|a, d|b, and find the maximum value of d.

There is a property: if d|a, d|b, then d|x×a+y×b

Assuming that the maximum value of d is s, and a>b, that is, s|a, s|b, then there is s | x×a+y×b,

Let x=1, y=-k, then s | a-kb, where k satisfies the condition k×b<=a, (k+1)×b>a

Then a-kb is equivalent to a%b

So there is a recurrence formula :, gcd(a,b)=gcd(b,a%b),a>bchoose the smallest two numbers to find the least common divisor, namely b and a%b

When b is 0, the recursion ends , because the divisor cannot be 0, at this time a is the greatest common divisor.

0 divided by any number is 0, that is, it can be divided evenly, so the greatest common divisor of 0 and a number is the number itself;

0 and 0 have no greatest common divisor.

Recursive template:

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

The best parameter here is a>=b, if it is less than that, it doesn't matter.

If the input is a=21, b=24, that is, gcd(21,24);

Then a%b=21%24=21, b=24, and then it becomes gcd(24,21); This is on the right track, just one more recursion.

Non-recursive template:

As mentioned above, b=0, then output a, a is the greatest common factor, the b of the nth recursion is 0, which means a%b==0 of the n-1th recursive transfer parameter, and a is the n-1th Recursive b, so in the n-1th recursion, if a%b is 0, you can exit the loop, and output b at this time.

if(a<b) swap(a,b);
int gcd(int a,int b)
{
    
    
    if (b==0) return a;
    int r=a%b;
    while (r) {
    
    
        a=b;
        b=r;
        r=a%b;
    }
    return b;
}

Non-recursive templates must determine the size of a and b to satisfy a>=b; recursive templates do not need.

Non-recursive templates must be specifically judged when b is 0 at the beginning; recursive templates are not required.

Least common multiple

lcm(a,b)=a*b/gcd(a,b);

But sometimes in order to prevent a * b from exceeding the defined data range, it can be written as lcm(a,b)=a/gcd(a,b)*b;

Find the greatest common factor of n numbers

int Gcds(int a[],int n) //数组从0到n-1
{
    
    
    int res=a[0];
    for (int i=1;i<n;i++) res=gcd(res,a[i]);
    return res;
}

Find the greatest common factor of n numbers

int Lcms(int a[],int n) //数组从0到n-1
{
    
    
    int res=a[0];
    for (int i=1;i<n;i++) res=lcm(res,a[i]);
    return res;
}

Guess you like

Origin blog.csdn.net/HangHug_L/article/details/114853110