数论

数论

https://www.zybuluo.com/wzq/note/454095

1.最大公约数gcd(辗转相除法:)

gcd(10,4)=gcd(4,2)=gcd(2,0)=2

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

2.最小公倍数lcm

lcm(10,4)=10/2*4=20;

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

3.埃拉托斯特尼筛法

(在10^7内可以很快的算出)复杂度(0(n))
从2开始 筛选 ,当该数字为质数时,就将后面该质数的倍数删掉,但这种方法会重复删一些数(2–>6, 3–>6).

const int maxn=(1e7)+5;
int Prime[maxn];

void Prepare_Prime()
{
  static bool isPrime[maxn];
  memset(isPrime,true,sizeof(isPrime));
  Prime[0]=0;//记录有多少个质数
  for(int i=2;i<maxn; i++)
    if(isPrime[i])
    {
      Prime[++prime[0]]=i;//储存质数
      for(int j=i+i; j<maxn; j+=i)  isPrime[j]=false;//删除该质数的倍数
    }
  printf("%d\n",Prime[0]);

}

4.欧拉筛选法 复杂度o(log n)

从2开始筛选 ,将筛选出的质数存入数组中, 将是质数倍数的数删除,当与质数相乘的数是指数的倍数,停止删除。
2 3 4 5 6 7 8 9 10 11 12

质数:2 3

  2 4 
  3 6 9
  4 8
  5 10
const int maxn=1e7+100;
int fp[maxn],pr[maxn],phi[maxn]  //fp[i]表示i的最小质因子,pr[0]表示质数的个数,pr[i]是质数数组,phi[i]是i的欧拉函数

void ola_prime(int n)
{
  memset(fp,0,sizeof(fp));
  pr[0]=0;
  for(int i=2; i<=n; i++)
  {
    if(!fp[i])
      {
         pr[++pr[0]]=i;fp[i]=i;phi[i]=i-1;
       }
     for(int j=1; j<=pr[0]; j++)
     {
         int k=i*pr[j];
         if(k>n) break;
         fp[k]=pr[j];
         if(k%pr[j]==0)
         {
            phi[k]=phi[i]*pr[j];
            break;
          }
          else  phi[k]=phi[i]*(pr[j]-1);
      }
   }
}

5.质因数分解

一个正数n,最多只有一个大于根号n的质因数,因此,枚举根号n以内的质数分解质因数。当最后的数不为1时,说明还有一个质数为n.

struct P_factor
{
    int p, k;
    P_factor() {p=k=0};
    p_factor(int a,int b)
    {
        p=a;k=b;
    }
};
vector<P_factor> divide_factor(int x)
{
    vector<P_factor> R;
    R.clear();
    for(int i=1; i<=Prime[0]; i++)//Prime[]为2-->sqrt(x)的质数数组
    {
        int p=Prime[i];
        if(p*p>x)  break;
        if(x%p==0)
        {
            int k=0;
            while(x%p==0)  k++,x/=p;
            R.push_back(P_factor(p,k));
        }
    }
    if(x>1)  R.push_back(P_factor(x,1));
    return 0;
}

质因数分解形式下的gcd和lcm
a = p1^k1 * p2^k2 … pm^km (ki>0)
b = p1^r1 * p2^r2 … pm^rm (ri>0)
gcd(a,b) = p1^min(k1,r1) * p2^min(k2,r2)… pm^min(km,rm)
lcm(a,b) = p1^max(k1,r1) * p2^max(k2,r2)… pm^max(km,rm)
例如:
100 = 2^2 * 5^2
40 =2^2 * 2^1 * 5^1
gcd(100,40) = 2^2 * 2^0 * 5^1=20
lcm(100,40) = 2^2 * 2^1 * 5^2 =200

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值