Acwing 870. 约数个数 数学

175 阅读2分钟

这道题我们套公式,约数个数=(x1+1)(x2+1)(x3+1)…(xk+1)

验证:

image.png

12可以分解为22×312^2 × 3^1 所以2可以取 0-3个,3种取法。3可以取0~1个,2种取法。一共有 2×3=62 × 3=6

也就是把一个数N变成它的质因数的次形式,写作:

N=(p1x1)×(p2x2)×(p3x3)×(pkxk)N=(p1^x1) × (p2^x2) ×(p3^x3) × …… (pk^xk)

那么N的约数个数就为它的质因数的指数+1相乘的结果,写作:

N的约数个数=x1+1)×(x2+1)×(x3+1)×(xk+1)N的约数个数=(x1+1) × (x2+1) × (x3+1) × …… (x^k+1)

code

我们先求出来n的所有质因数,用一个map来存放质因数和指数,最后用公式求出约数个数

其中求质因数的话我们是这样求的:

for(int i=2;i<=n/i;i++)if(n%i==0)h[i++],cnt++;

cnt++的话就是相同的质数的指数++

得出来的就是20=23+31+51 20=2^3+3^1+5^1

870. 约数个数 - AcWing题库

思想

这道题要我们求(a×b×c)mod (a×b×c)mod q的值。

根据题目给的数据范围我们可知,把它们全部相乘之后再 mod 肯定是爆内存了。

因此我们可以用求约数个数的公式:N的约数个数=x1+1)×(x2+1)×(x3+1)×(xk+1)N的约数个数=(x1+1) × (x2+1) × (x3+1) × …… (x^k+1)

先把a,b,c三个数分别化为自己的质因数幂形式,然后再+1相乘,因为数有可能还是很大,所以还是要取模。

#include<iostream>
#include<unordered_map>
using namespace std;
const int mo=1e9+7;
unordered_map<int,int> h;//用来存放质因数以及它对应的指数
typedef long long LL;
int n;

//分解质因数
void get_divisors(int n)
{
    for(int i=2;i<=n/i;i++)
    {
        while(n%i==0)
        {
            h[i]++; //i对应的质数的次方+1
            n/=i;//除尽i
        }
    }

        if(n>1)h[n]++;//保留最后一个质因数


    //以上功能就完成了存放所有质因数的指数个数
}
int main()
{
    cin>>n;
    while(n--)
    {
        int a=0;
        cin>>a;

        get_divisors(a);
    }

    LL res=1;//res用来存放答案,答案的值可能很大,所以用long long 
    for(auto iter:h)
    {
        res=res*(iter.second+1)%mo;//N的约数个数=(x1+1) × (x2+1) × (x3+1) × …… (x^k+1)
    }
    cout<<res<<endl;
    return 0;
}

}