ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数论基础

2022-07-11 09:05:48  阅读:171  来源: 互联网

标签:prime 约数 return gcd 数论 基础 int 素数


最大公因数(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;
理解:

  • 当 i是prime[j]的倍数时,i = k × prime[j],
  • 如果继续运算 j+1,
    • i × prime[j + 1] = prime[j] × k × prime[j+1]
  • 这里prime[j]是最小的素因子,当i = k × prime[j+1]时会重复,
  • 所以跳出循环。

举个例子 :

  • i = 8 ,j = 1,prime[j] = 2,

如果不跳出循环,

  • prime[j+1] = 3, 8 * 3 = 2 * 4 * 3 = 2 * 12,
    在i = 12时会计算。

代码

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有