zoukankan      html  css  js  c++  java
  • 数论基本定理

    数论基本定理

    (1).唯一分解定理

    一句话:   
    任何大于1的自然数,都可以唯一分解成有限个质数的乘积
    例如对于大于1的自然数n,
    N = p1r1p1r1 * p2r2p2r2 * p3r3p3r3 * * * * * * pnrnpnrn ( 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 = p1r1p1r1 * p2r2p2r2 * p3r3p3r3 * * * * * * pnrnpnrn

    sum=(r1+1)(r2+1)(r3+1)(rn+1);sum=(r1+1)(r2+1)(r3+1)∗∗∗∗∗(rn+1);


    ( 2 ) ,求一个数所有的因子和
    N = p1r1p1r1 * p2r2p2r2 * p3r3p3r3 * * * * * * pnrnpnrn

    ans=p1r1+11p11p2r2+11p21p3r3+11p31pnrn+11pn1ans=p1r1+1−1p1−1∗p2r2+1−1p2−1∗p3r3+1−1p3−1∗∗∗∗∗∗pnrn+1−1pn−1


    ( 3 ) ,转换GCD和LCM
    N = p1r1p1r1 * p2r2p2r2 * p3r3p3r3 * * * * * * pnrnpnrn
    M = p1l1p1l1 * p2l2p2l2 * p3l3p3l3 * * * * * * pnlnpnln

    GCD=p1min(r,l1)p2min(l2,r2)p3min(l3,r3)pnmin(ln,rn)GCD=p1min(r,l1)∗p2min(l2,r2)∗p3min(l3,r3)∗∗∗∗∗∗pnmin(ln,rn)
    LCM=p1max(r,l1)p2max(l2,r2)p3max(l3,r3)pnmax(ln,rn)LCM=p1max(r,l1)∗p2max(l2,r2)∗p3max(l3,r3)∗∗∗∗∗∗pnmax(ln,rn)

    ( 2 ) , 容斥定理

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

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


    用法:
    如果要对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 - sum);
        }
        return 0;
    }
    /* 题目要求1..n-1中与n互质的数的个数 */
  • 相关阅读:
    yum和apt-get用法及区别
    Vim终极指南:所思即所得
    Vim 操作符命令和动作命令
    vim中文手册
    标准代码页(codepage)列表
    中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030
    vim在系统剪切板的复制与粘贴
    linux中高亮显示文本的工具 -- bat
    pandas category数据类型
    pandas 数据类型转换
  • 原文地址:https://www.cnblogs.com/Nlifea/p/11745980.html
Copyright © 2011-2022 走看看