数论 - 约数 - 试除法求约数 + 约数个数 + 约数之和

数论 - 约数 - 试除法求约数 + 约数个数 + 约数之和 + 最大公约数

1、 试出法求约数

给定n个正整数ai,对于每个整数ai,请你按照从小到大的顺序输出它的所有约数。

输入格式
第一行包含整数n。

接下来n行,每行包含一个整数ai。

输出格式
输出共n行,其中第 i 行输出第 i 个整数ai的所有约数。

数据范围
1≤n≤100,
2≤ai≤2∗109

输入样例:
2
6
8
输出样例:
1 2 3 6 
1 2 4 8 

分析:

O ( n ) 的 做 法 , 枚 举 一 个 较 小 的 因 子 , 另 一 个 直 接 用 原 数 去 除 。 O(\sqrt{n})的做法,枚举一个较小的因子,另一个直接用原数去除。 O(n )

注 意 完 全 平 方 数 只 要 加 入 一 个 因 子 。 注意完全平方数只要加入一个因子。

代码:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

const int N=110;

int n;

void solve(int x)
{
    vector<int> p;
    for(int i=1;i<=x/i;i++)
        if(x%i==0) 
        {
            p.push_back(i);
            if(i!=x/i) p.push_back(x/i);
        }
    
    
    sort(p.begin(),p.end());
    
    for(int i=0;i<p.size();i++) cout<<p[i]<<' ';
    cout<<endl;
}

int main()
{
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        solve(x);
    }
    
    return 0;
}

2、约数个数

给定n个正整数ai,请你输出这些数的乘积的约数个数,答案对109+7取模。

输入格式
第一行包含整数n。

接下来n行,每行包含一个整数ai。

输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对109+7取模。

数据范围
1≤n≤100,
1≤ai≤2∗109

输入样例:
3
2
6
8
输出样例:
12

正 整 数 a 的 约 数 个 数 : 由 算 术 基 本 定 理 , 设 A = P 1 a 1 P 2 a 2 . . . P k a k , 则 A 的 约 数 个 数 为 ( a 1 + 1 ) ( a 2 + 1 ) . . . ( a k + 1 ) 。 正整数a的约数个数:\\由算术基本定理,设A=P_1^{a_1}P_2^{a_2}...P_k^{a_k},则A的约数个数为(a_1+1)(a_2+1)...(a_k+1)。 aA=P1a1P2a2...PkakA(a1+1)(a2+1)...(ak+1)

说 明 : 设 A 的 一 个 约 数 A ′ = P 1 b 1 P 2 b 2 . . . P k b k , 其 中 b i ∈ [ 0 , a i ] , i ∈ [ 1 , k ] 。 说明: \\设A的一个约数A'=P_1^{b_1}P_2^{b_2}...P_k^{b_k},其中b_i∈[0,a_i],i∈[1,k]。 AA=P1b1P2b2...Pkbkbi[0,ai]i[1,k]

每 一 个 k 元 组 ( b 1 , b 2 , . . . , b k ) 均 能 对 应 A 的 一 个 约 数 , 对 于 每 个 b i 都 有 a i + 1 种 取 值 , \\每一个k元组(b_1,b_2,...,b_k)均能对应A的一个约数,对于每个b_i都有a_i+1种取值, k(b1,b2,...,bk)Abiai+1

根 据 乘 法 原 理 , 不 同 的 k 元 组 的 个 数 即 A 的 所 有 约 数 的 个 数 为 C a 1 + 1 1 C a 2 + 1 1 . . . C a k + 1 1 = ( a 1 + 1 ) ( a 2 + 1 ) . . . ( a k + 1 ) 。 根据乘法原理,不同的k元组的个数即A的所有约数的个数为C_{a_1+1}^1C_{a_2+1}^1...C_{a_k+1}^1=(a_1+1)(a_2+1)...(a_k+1)。 kACa1+11Ca2+11...Cak+11=(a1+1)(a2+1)...(ak+1)

具体落实:

问 题 转 化 分 解 A 的 所 有 质 因 数 并 保 存 每 个 质 因 数 的 指 数 , 再 用 公 式 。 问题转化分解A的所有质因数并保存每个质因数的指数,再用公式。 A

代码:

#include<iostream>
#include<unordered_map>

#define ll long long
#define x first
#define y second

using namespace std;

const int mod=1e9+7;

int n;
unordered_map<int,int> P;

int main()
{
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        for(int i=2;i<=x/i;i++)
            while(x%i==0)
            {
                x/=i;
                P[i]++;
            }
        if(x>1) P[x]++;
    }
    
    ll res=1;
        for(auto p: P)
            res=res*(p.y+1)%mod;
        
    cout<<res<<endl;
    
    return 0;
}

3、约数之和

给定n个正整数ai,请你输出这些数的乘积的约数之和,答案对109+7取模。

输入格式
第一行包含整数n。

接下来n行,每行包含一个整数ai。

输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对109+7取模。

数据范围
1≤n≤100,
1≤ai≤2∗109

输入样例:
3
2
6
8
输出样例:
252

正 整 数 a 的 约 数 个 数 : 由 算 术 基 本 定 理 , 设 A = P 1 a 1 P 2 a 2 . . . P k a k , 则 A 的 约 数 之 和 为 ∏ i = 1 k ∑ j = 0 a i P i j 。 正整数a的约数个数:\\由算术基本定理,设A=P_1^{a_1}P_2^{a_2}...P_k^{a_k},则A的约数之和为\prod_{i=1}^k\sum_{j=0}^{a_i}P_i^j。 aA=P1a1P2a2...PkakAi=1kj=0aiPij

即 ( P 1 0 + P 1 1 + . . . + P 1 a 1 ) ( P 2 0 + P 2 1 + . . . + P 2 a 2 ) . . . ( P k 0 + P k 1 + . . . + P k a k ) 即(P_1^0+P_1^1+...+P_1^{a_1})(P_2^0+P_2^1+...+P_2^{a_2})...(P_k^0+P_k^1+...+P_k^{a_k}) (P10+P11+...+P1a1)(P20+P21+...+P2a2)...(Pk0+Pk1+...+Pkak)

说 明 : 说明:
设 A 的 一 个 约 数 A ′ = P 1 b 1 P 2 b 2 . . . P k b k , 其 中 b i ∈ [ 0 , a i ] , i ∈ [ 1 , k ] 。 设A的一个约数A'=P_1^{b_1}P_2^{b_2}...P_k^{b_k},其中b_i∈[0,a_i],i∈[1,k]。 AA=P1b1P2b2...Pkbkbi[0,ai]i[1,k]

每 一 个 k 元 组 ( b 1 , b 2 , . . . , b k ) 均 能 对 应 A 的 一 个 约 数 , 对 于 每 个 质 因 子 P i x , x 均 有 a i + 1 种 选 法 , 每一个k元组(b_1,b_2,...,b_k)均能对应A的一个约数,对于每个质因子P_i^{x},x均有a_i+1种选法, k(b1,b2,...,bk)APixxai+1

现 需 在 k 个 形 如 { P i 0 , P i 1 , . . . , P i a i } 的 集 合 中 选 一 个 p i x , i ∈ [ 1 , k ] , x ∈ [ 0 , a i ] , 现需在k 个形如\{P_i^0,P_i^1,...,P_i^{a_i}\}的集合中选一个p_i^{x},i∈[1,k],x∈[0,a_i], k{Pi0Pi1...Piai}pixi[1,k],x[0,ai]

选 k 次 , 每 次 对 应 一 个 约 数 P 1 x 1 P 2 x 2 . . . P k x k , 最 终 求 和 结 果 为 : 选k次,每次对应一个约数P_1^{x_1}P_2^{x_2}...P_k^{x_k},最终求和结果为: kP1x1P2x2...Pkxk: ( P 1 0 + P 1 1 + . . . + P 1 a 1 ) ( P 2 0 + P 2 1 + . . . + P 2 a 2 ) . . . ( P k 0 + P k 1 + . . . + P k a k ) (P_1^0+P_1^1+...+P_1^{a_1})(P_2^0+P_2^1+...+P_2^{a_2})...(P_k^0+P_k^1+...+P_k^{a_k}) (P10+P11+...+P1a1)(P20+P21+...+P2a2)...(Pk0+Pk1+...+Pkak)

具体落实:

① 、 首 先 对 A 分 解 质 因 数 , 并 记 录 每 个 质 因 数 的 指 数 , 用 一 个 哈 希 表 存 储 。 ①、首先对A分解质因数,并记录每个质因数的指数,用一个哈希表存储。 A

② 、 求 P i 0 + P i 1 + P i 2 + . . . + P i a i 可 以 用 迭 代 来 做 , t = t ∗ P i + 1 , 迭 代 a i + 1 次 。 当 然 也 可 以 用 等 比 数 列 求 和 公 式 、 分 治 等 方 法 。 ②、求P_i^{0}+P_i^{1}+P_i^{2}+...+P_i^{a_i}可以用迭代来做,t=t*P_i+1,迭代a_i+1次。\\\qquad当然也可以用等比数列求和公式、分治等方法。 Pi0+Pi1+Pi2+...+Piait=tPi+1ai+1

代码:

#include<iostream>
#include<unordered_map>

#define ll long long
#define x first
#define y second

using namespace std;

const int mod=1e9+7;

int n;
unordered_map<int,int> prime;

int main()
{
    cin>>n;
    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]++;
    }
    
    ll res=1;
    for(auto p : prime)
    {
        ll t=0;
        for(int i=0;i<=p.y;i++)
            t=(t*p.x+1)%mod;
        res=res*t%mod;
    }
    
    cout<<res<<endl;
    
    return 0;
    
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值