数论基本定理

数论基本定理

(1).唯一分解定理

一句话:   
任何大于1的自然数,都可以唯一分解成有限个质数的乘积
例如对于大于1的自然数n,
N = p1r1 p 1 r 1 * p2r2 p 2 r 2 * p3r3 p 3 r 3 * * * * * * pnrn p n r n ( ps: p1,p2,p2都是质数 )
代码实现:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

//利用唯一分解定理拿下所有的质因子 

const int maxn = 1e5+5;

int v[maxn];

int main(){
    int pos = 0;
    int t; cin>>t;
    for (int i = 2;i*i <= t;){
        bool flag = false;
        while ( t % i == 0 ) {
            if(!flag){
                flag = true;
                v[pos++] = i;
            } t /= i;
        }
        if(i == 2) i++;
        else i+= 2;//时间小优化 
    }
    if ( t != 1 ) v[pos++] = t;//判断最后一位是不是1,还是质数

    return 0;
}

用途:
( 1 ) ,
求一个数有几个因子
N = p1r1 p 1 r 1 * p2r2 p 2 r 2 * p3r3 p 3 r 3 * * * * * * pnrn p n r n

sum=(r1+1)(r2+1)(r3+1)(rn+1); s u m = ( r 1 + 1 ) ( r 2 + 1 ) ( r 3 + 1 ) ∗ ∗ ∗ ∗ ∗ ( r n + 1 ) ;

( 2 ) ,求一个数所有的因子和
N = p1r1 p 1 r 1 * p2r2 p 2 r 2 * p3r3 p 3 r 3 * * * * * * pnrn p n r n
ans=p1r1+11p11p2r2+11p21p3r3+11p31pnrn+11pn1 a n s = p 1 r 1 + 1 − 1 p 1 − 1 ∗ p 2 r 2 + 1 − 1 p 2 − 1 ∗ p 3 r 3 + 1 − 1 p 3 − 1 ∗ ∗ ∗ ∗ ∗ ∗ p n r n + 1 − 1 p n − 1

( 3 ) ,转换GCD和LCM
N = p1r1 p 1 r 1 * p2r2 p 2 r 2 * p3r3 p 3 r 3 * * * * * * pnrn p n r n
M = p1l1 p 1 l 1 * p2l2 p 2 l 2 * p3l3 p 3 l 3 * * * * * * pnln p n l n
GCD=p1min(r,l1)p2min(l2,r2)p3min(l3,r3)pnmin(ln,rn) G C D = p 1 m i n ( r , l 1 ) ∗ p 2 m i n ( l 2 , r 2 ) ∗ p 3 m i n ( l 3 , r 3 ) ∗ ∗ ∗ ∗ ∗ ∗ p n m i n ( l n , r n )

LCM=p1max(r,l1)p2max(l2,r2)p3max(l3,r3)pnmax(ln,rn) L C M = p 1 m a x ( r , l 1 ) ∗ p 2 m a x ( l 2 , r 2 ) ∗ p 3 m a x ( l 3 , r 3 ) ∗ ∗ ∗ ∗ ∗ ∗ p n m a x ( l n , r n )

( 2 ) , 容斥定理

看下列Vann图:
这里写图片描述
表示成为公式如下:

|ni=1Ai|=CB(1)size(c)1|eCe| | ∪ i = 1 n ∗ A i | = ∑ C ⊆ B ∗ ( − 1 ) s i z e ( c ) − 1 | ∩ e ∈ C e |

用法:
如果要对n个物体进行选择,那么有多少种情况
我们可以考虑进行二进制枚举:
实现代码如下:
ad : 小练习

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

const int maxn = 1e5+5;

int v[maxn];

int main(){
    int t,n;
    while(scanf("%d",&t) && t)
    {
        int ss = 1; n = t;
        for (int i = 2;i * i <= t;){
            bool flag = false;
            while(t%i == 0){
                if(!flag){
                    flag = true;
                    v[ss++] = i;
                }t /= i;
            }
            if ( i == 2 ) i++;
            else i += 2;
        }
        ll sum = 0;
        if (t != 1) v[ss++] = t; ss -= 1;
        for (int i = 1;i < (1 << ss);i++){ // 这里以二进制的形式进行枚举
            ll cnt = 0,tmp = 1;
            for (int j = 1; j <= ss ;j++){
                if ( i >> (j-1) & 1 )  {
                    cnt++;
                    tmp = tmp * v[j];
                } 
            }
            if(cnt & 1) sum += n  / tmp;
            else sum -= n / tmp;
        }
        printf("%d\n",n - sum);
    }
    return 0;
}
/* 题目要求1..n-1中与n互质的数的个数 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值