首页 > 其他分享 >..约数..

..约数..

时间:2024-07-12 17:57:19浏览次数:13  
标签:约数 prime .. int 最大公约数 include mod

先做回顾

1、什么是约数?
在数学中,一个数的约数(Divisor)是能够整除这个数的所有正整数。换句话说,如果一个正整数 d 能够被另一个正整数 n 整除,那么 d 就是 n 的一个约数。

2、算术基本定理——唯一分解定理

它指出,每个大于1的自然数都可以唯一地表示为若干个质数的乘积,而且这些质数的次序是不重要的。换句话说,质因数分解是唯一的,除了质因数的顺序之外。

算术基本定理包含两个部分:

  1. 存在性:每个大于1的自然数都可以分解为质数的乘积。
  2. 唯一性:这种分解是唯一的,不考虑质因数的顺序。

例如,数字60可以分解为质数的乘积:60=2^2×3^1×5^1。这是60的唯一质因数分解,尽管我们可以改变质因数的顺序,例如写成 60=5^1×3^1×2^2,但这仍然被认为是相同的分解。

3、除、除以、除数、被除数

a除b=b/a,a除以b=a/b,当x/y时x是被除数,y是除数

4、C++ STL里的哈希表(unordered_map)。unordered_map 是 C++ 标准库中的一个关联容器,它提供了一种基于哈希表的关联容器实现。unordered_map允许以平均常数时间复杂度(O(1))访问容器中的元素,这比传统的基于红黑树实现的map容器(平均时间复杂度为 O(log n))要快。

unordered_map<int,int> hash;第一个int存储的是键,后者存储的是对应键的值。其中键是唯一的,值可以是任意。若想插入值:hash.insert({1,2})或者hash[1]=2,都表示插入键值对 (1, 2),键:1,值:2。

5、for(auto hash1:hash) 表示遍历该哈希表中的每一个键值对。若不想遍历完,只是遍历到某一特定值k时可以for (auto it = prime.begin(); it != prime.find(k); ++it) { ... }。当然,如果想从某一特定的值开始遍历时(假设为m),则可以初始值auto it=prime.find(m)。此外,这里的auto可以替换为pair<int,int>类型。

题目;869. 试除法求约数 - AcWing题库

思路:
求出来约数,sort一下即可,具体见代码。

代码:

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

using namespace std;

int n;
int a[100010],b[100010],ans,cnt;

/*
由于约数是成对出现的,所以只需要求出较小的那一方,然后直接计算出另一方即可
比如求出8的一个约数为2,那么另一个约数自然为8/2=4。
*/
void get_factor(int u)
{
    for(int i=1;i<=u/i;i++)
    {
        if(u%i==0)
        {
            a[ans++]=i;
            if(i!=u/i)
            a[ans++]=u/i;
        }
    }
    
    sort(a,a+ans);
    
    for(int i=0;i<ans;i++) cout << a[i] << " ";
    cout << endl;
    return;
}

int main()
{
    cin >> n;
    while(n--)
    {
        int x;
        cin >> x;
        memset(a,0,sizeof a);
        ans=0;
        get_factor(x);
    }
    
    return 0;
}

 

 约数个数与约数之和

由算数基本定理可得:任何一个数N都可以表示为:

 其中p1​,p2​,…,pk​ 是质数,e1​,e2​,…,ek​ 是对应的指数。

那么求解约数的个数的公式为:(e1+1)*(e2+1)*......*(ek+1)
证明:

求约束的个数,也就是从上述不同质因子里边挑出来一个值,那么排列组合即可得证。
贴一张:

 不难发现约数之和的公式为:(p1^0+p1^1+...+p1^e1)*(p2^0+p2^1+...+p2^e2)*...*(pk^0+pk^1+...+pk^ek)。后续题目里会模拟样例,瞟一眼模拟就明白了

题目:870. 约数个数 - AcWing题库

用试除法求出质因子的底数与质数,然后带一下公式即可 

 代码:

//int范围内,约数最多的个数在1500左右
#include<iostream>
#include<cstring>
#include<unordered_map>

using namespace std;

const int mod=1e9+7;

int main()
{
    int n;
    cin >> n;
    
    unordered_map<int,int> prime;
    while(n--)
    {
        int x;
        cin >> x;
        /*
        这里边输入边取出x的底数与指数,而不是先乘出结果再对质因数进行取底数与指数
        1、先计算完乘的结果是没有必要的,因为每个数对应的质因数的底数相同。
        比如:计算8*16*14的约数个数
        ①若先乘完结果:1729=2^8*7^1,那么对应的约数的个数就是(8+1)*(1+1)=18。
        ②若非如此:先将8的质因数取底数与指数:prime[2]=3(这里会自加三次,因为8=2^3)。
        然后将16的质因数取底数与指数:prime[2]=7(在前者8的基础上又自加了四次,16=2^4)。
        最后操作14:prime[2]=8,prime[7]=1。那么循环遍历后就会得到质因数2的指数为8,7的指数为1
        最后套用公式即可求解。
        2、若先乘完,必然会爆int(题目一定不会让你那么轻松(⊙o⊙)),所以不得不采用第二种方法。
        */
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                prime[i]++;
            }
        }
        if(x>1) prime[x]++;
    }
    
    long long res=1;
    for(auto primes:prime) res=res*(primes.second+1)%mod;
    cout << res;
    
    return 0;
}

题目: AcWing 871. 约数之和 - AcWing

代码: 

/*
模拟一下样例:上述的约数个数可分解为:2^5*3^1=96(这里可以手动求,也可以用867的代码求)
那么它的约数就是:1 2 3 4 6 8 12 16 24 32 48 96 (试除法求约束)
也就是:2^0*3^1+2^1*3^1+2^2*3^1+2^3*3^1+2^4*3^1+2^5*3^1+2^0*3^0+2^1*3^0+2^2*3^0+2^3*3^0+2^4*3^0+2^5*3^0
即3+6+12+24+48+96+1+2+4+8+16+32,也就是(2^0+2^1+2^2+2^3+2^4+2^5)*(3^0+3^1)
我们可以发现约数之和=每个质因数的和相乘(这里的和即是等比数列的求和)
*/
#include<iostream>
#include<cstring>
#include<unordered_map>
#include<cmath>

using namespace std;

const int mod=1e9+7;
int n;
int main()
{
    cin >> n;
    unordered_map<int,int> prime;
    while(n--)
    {
        int x;
        cin >> x;
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                prime[i]++;
            }
        }
        
        if(x>1) prime[x]++;
    }
    long long res=1;
    for(auto primes:prime) 
    {
        int a=primes.first,b=primes.second;
        long long t=1;
        //这里等比求和用秦九韶公式,因为秦九韶是相乘,不涉及除运算
        while(b -- ) t=(a*t+1)%mod;
        res=res*t%mod;
    }
    
    cout << res;
    return 0;
}

 

欧几里得——辗转相除法

如果a,b的最大公约数为d那么gcd(a,b)=gcd(b,a mod b)

证明:d | a(d整除a)、d | b 那么就有d | (a+b)、d | (x*a+y*b)。
充分性:当d | a,d | b时(假设(a,b)的最大公约数为:d)
要证充分性,我们需要证明(a,b)的最大公约数d为(b,a mod b)的最大公约数
    a mod b=a-(a/b)*b(这里括号里取整),设常数c=(a/b),那么就有a mod b=a-c*b,那么根据d | (x*a+y*b),而此时令x=1,y=-c所以可得:d | (a mod b),又因为d | b所以d为(b,a mod b)的最大公约数
必要性:当d | b、d | a mod b 时(假设(a,b)的最大公约数为:d)
要证充分性,我们需要证明(b,a mod b)的最大公约数d为(a,b)的最大公约数
     a mod b=a-(a/b)*a,设常数c=(a/b),那么就有a mod b=a-c*b,因为d | b所以d | (x*b+y*(a mod b))这里令x=c y=1则有d | (c*b+a-c*b)→d | a 所以d | a又因为d | b 所以d为gcd(a,b)的最大公约数。

则gcd(a,b)=gcd(b,a mod b)得证

题目:AcWing 872. 最大公约数 - AcWing

代码:

//欧几里得算法——辗转相除法

#include<iostream>
#include<cstring>

using namespace std;

int n;

int gcd(int a,int b)
{
    //当b等于0时,最大公约数就为a。不等于0时,进行递归寻找最大公约数
    return b?gcd(b,a%b):a;
}

int main()
{
    scanf("%d",&n);
    while(n--)
    {
        int a,b;
        cin >> a >> b;
        printf("%d\n",gcd(a,b));
    }
    
    return 0;
}

标签:约数,prime,..,int,最大公约数,include,mod
From: https://blog.csdn.net/2301_80358171/article/details/140382959

相关文章

  • ..质数..
    先弄清楚我们在上小学时学的概念。1、什么是质因数?   -质因数是指能够整除给定正整数的质数。每个正整数都可以被表示为几个质数的乘积,这些质数就是该数的质因数。质因数分解是将一个正整数分解成若干个质数相乘的过程。例如,数字12的质因数分解是2×2×3,因此2......
  • insert into....select从一个数据库的表中导入到另一个数据库的表中
    说明已知条件:有两台oracle数据库,ora1和ora2,ora1的表中有数据(ip:192.0.0.1,表名table1,用户名和密码:yth(有管理员的权限),数据库服务名:orcl),需要导入ora2中(ip:192.0.0.2,表名table2,用户名和密码:ythcj(有管理员的权限),数据库服务名:orcl)。1.在ora2中建立数据库的链接指向ora1(需要有管理员......
  • Lbview调用python脚本报错:错误1667...无法导入指定的python模块
    前提注意:NILabVIEW2021(32位)Python3.9.10(32位)32位对应32位,64位同理,否则可能会报错报错的原因:LabVIEW中使用的Python环境与安装的Python包不匹配也就是说Labview中使用的是python版本安装的系统路径,而PyCharm使用的虚拟环境路径,它的包都是下载到项目文件夹内可......
  • Failed to configure a DataSource: 'url' attribute is not specified and no embe..
    原文链接: https://www.cnblogs.com/javawxid/p/10949511.html问题原因:Mybatis没有找到合适的加载类,其实是大部分spring-datasource-url没有加载成功,分析原因如下所示.DataSourceAutoConfiguration会自动加载.没有配置spring-datasource-url 属性.spring......
  • spark程序在hdfs集群执行,提示: “main“ org.apache.spark.SparkException: Failed to
    1.执行代码spark在hadoop上以集群模式执行代码bin/spark-submit\--masteryarn\--deploy-modecluster\--executor-memory1G\--total-executor-cores2\/root/word_count_cluster.py2.错误截图错误原因:找不到spark目录3.解决办法在/etc/profile文件中配置spa......
  • Maven工程下:alibaba fastjson2的各种序列化:java对象转json对象、json对象转java对象
    pom文件导入fastjson2坐标:<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.51</version></dependency>UserVO对象:@Data@AllArgsConstructor......
  • 近似排序......
    一年没动算法的蒻蒟随手点开了之前做过的一道【近似排序】,然后开始了,恢复之旅......TFLSOJ【近似排序】看到题目经简单分析后先写出了一种傻瓜解法,(可能叫暴力??)#include<bits/stdc++.h>usingnamespacestd;intx,y;inta[110];intmain(){ cin>>x>>y; for(inti=x,j=1......
  • AI算法/模型/框架/模型库...都是什含义区别和联系?
    AI算法、模型、框架、模型库…都是什含义/区别和联系?算法、模型、模型库、框架什么是算法(Algorithm)?算法(Algorithm):算法是解决某一特定问题的步骤或规则集合。在AI/ML领域中,算法是用于训练模型、优化参数和执行推理的数学规则和计算方法。算法是模型训练的核心,通过......
  • 解决nacos报错 Caused by: io.grpc.netty.shaded.io.netty.channel.unix.Errors$Nati
    报错信息:org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)atorg.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)atorg......
  • 第K个约数
    题目链接:https://bzoj.org/p/3758Description给你一个数字N,再给个数字K将N的所有约数从小到大排好,求第K个约数,如果不存在输出-1Input一行给出N,KN<=1e15K<=1e9Output如题Samples输入数据142输出数据12当我刚开始看见尝试:7已通过:2难度:10时,有点退缩的......