其他分享
首页 > 其他分享> > 数论基础

数论基础

作者:互联网

最大公因数(gcd)

辗转相除法
运算速度: O(n)
计算公式:gcd(a,b) = gcd(b,a mod b)
代码:

int gcd(int a,int b)
{
    int  c=a%b;
    while(c!=0)
    {
        a=b;
        b=c;
        c=a%b;
    }
    return b;
}

最小公倍数(lcm)

最小公倍数可以通过最大公约数求:最小公倍数 = 两数之和 / 最大公约数。
image

int lcm(int a,int b)
{
    return a*b/gcd(a,b);
}

素数

欧拉线性素数筛

原理

基本思想 :
在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
关键:
if(i%prime[j]==0)break;
理解:

举个例子 :

如果不跳出循环,

代码

bool visited[100100];//初始化
long long prime[100100];//保存素数
int cnt;

void Euler_prime()
{
    memset(visited, true,sizeof (visited) );
    visited[1]=false;
    for(int i=2;i<100100;i++)
    {
        if(visited[i]) prime[cnt++]=i;
        for(int j=0;j<cnt&&i*prime[j]<100100;j++)
        {
            visited[i*prime[j]] = false;
            if(i%prime[j]==0)//关键
                break;
        }
    }
}

实战

试除法判断素数

复杂度:O( \(\sqrt n\) )
原理:约数成对出现(完全平方数除外)
代码:

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

素数定理

[1,N]中素数的个数约为NlgN。
则从[1,N]中人选一个数,其为质数的概率为1/lgN。

算数基本定理

任意一个整数都能被分解为如下形式:
\(n=p^{k_{1}}_{1}×p^{k_{2}}_{2}×....×p^{k_{t}}_{t}\)。 其中p为质数。

约数

求是X的约数的个数

题意: 共有 N 个整数 A1,A2,…,AN,对于每一个数 Ai,求其他的数中有多少个是它的约数。
思路: 对于每个数判断其他数是不是他的倍数。
1291. 轻拍牛头

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;

typedef pair<int, int> pii;
const int N = 1e6 + 10;
const int INF = 0x3f3f3f3f3f;

int n;
int a[N];
int cnt[N],st[N];
void slove()
{
    cin>>n;
    for(int i=1;i<=n;i++){
      cin>>a[i];
      st[a[i]]++;
    } 
    for(int i=1;i<=N;i++){
      if(!st[i])  continue;
      cnt[i]+=st[i]-1;
      for(int j=i+i;j<=N;j+=i){
        if(st[j])
        cnt[j]+=st[i];
      }
    }
    for(int i=1;i<=n;i++){
      cout<<cnt[a[i]]<<endl;
    }
}

signed main()
{
  // int t;
  // cin >> t;
  // while (t--)
  slove();

  return 0;
}

标签:prime,约数,return,gcd,数论,基础,int,素数
来源: https://www.cnblogs.com/kingwz/p/15247937.html