(寒假练习 AcWing 870)约数个数(数论)

原题链接(戳我~)

题目描述

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

输入格式

第一行包含整数n。

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

输出格式

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

数据范围

$ 1≤n≤100,$
\(1≤ai≤2?10^9\)

输入样例:

3
2
6
8

输出样例:

12

解题思路

根据算数的进本定理可知任何一个大于1的自然数N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 \(N=P_1^{a_1}\times P_2^{a_2} \times P_3^{a_3} \times P_4^{a_4}\times...\times P_n^{a_n}(P_1,P_2,P_3...P_n均为质数)\) 那么该数 N 的约数个数为: \((a1 + 1)\times (a_2 + 1)\times (a_3 + 1)\times (a_4 + 1)\times ...\times (a_n+1)\) 所以我们直接根据公式一步步向下求即可。

  • 看了许多dalao们写的题解全部都是用了一个叫“unordered_map”的容器。emmm......有关unordered_map的讲解请移步至(STL之unordered_map)暂时未写

代码样例

#include<iostream>
#include<unordered_map>
using namespace std;
typedef long long ll;

const ll MOD = 1e9 + 7;
unordered_map<int,int> hash;

int main(){
    int t;
    cin >> t;
    while(t--){   // 质因数分解
        ll n;
        cin >> n;
        for (int i = 2; i*i <= x; ++i){
            while(n % i == 0){
                hash[i] ++;
                n /= i;
            }
        }
        if (n > 1)
            hash[n] ++;  // 这一步不要忘记了
    }
    ll ans = 1;
    for (auto n:hash){  // 约数的个数 (N1 + 1)*(N2 + 1)*(N3 + 1)*...
        ans = ans*(n.second + 1) % MOD;  // 别忘了取模
    }
    cout << ans << endl;
    return 0;
}

完~

原文地址:https://www.cnblogs.com/cafu-chino/p/12237912.html

时间: 2024-10-11 06:07:14

(寒假练习 AcWing 870)约数个数(数论)的相关文章

hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4542 小明系列故事--未知剩余系 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 889    Accepted Submission(s): 207 Problem Description "今有物不知其数,三三数之有二,五五数之有三,七七数之有

数论线性筛总结 (素数筛,欧拉函数筛,莫比乌斯函数筛,前n个数的约数个数筛)

线性筛 线性筛在数论中起着至关重要的作用,可以大大降低求解一些问题的时间复杂度,使用线性筛有个前提(除了素数筛)所求函数必须是数论上定义的积性函数,即对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数,若a,b不互质也满足的话则称作完全积性函数,下面说明每个筛子是怎么筛的. 最基础的是素数筛,其它三个筛都是以素数筛为前提 素数筛 void get_prime() { int pnum = 0; for(int i = 2;

最大约数个数算法分析

   最大约数个数算法分析   实验问题描述 正整数x的约数是能整除x的正整数.正整数x的约数个数记为div(x),例如,1,2,5,10都是正整数10的约数,且div(10)=4.设a和b是2个正整数,a<=b,找出a和b当中约数个数最多的数x,输出其约数个数值.   实验目的 本次实验通过利用数论知识,建立素数表,弥补累除法在时间复杂度上的缺陷,同时又结合累除法在小范围内能够计算出最准确的约数个数的特性, 在时间复杂度上获得最大的优化.   实验知识准备过程 累除法的基本思想:计算正整数a的

luogu3327 [SDOI2015]约数个数和

link 设\(d(x)\)表示x约数个数,给定n,m,\(\sum_{i=1}^n\sum_{j=1}^md(ij)\) 多组询问,1<=T<=50000,1<=N, M<=50000 前置知识:\(d(ij)=\sum_{x|i}\sum_{y|j}[\gcd(x,y)=1]\) 证明:\(xy\)一定是\(ij\)的约数.考虑一个质数\(p\),\(i\)中包含\(p^a\),\(j\)中包含\(p^b\),则\(ij\)中包含的是\(p^{a+b}\).若\(\gcd(x,

[BZOI 3994] [SDOI2015]约数个数和

[BZOI 3994] [SDOI2015]约数个数和 题面 设d(x)为x的约数个数,给定N.M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\) T组询问,\(N,M,T \leq 50000\) 分析 首先有一个结论 \[d(nm)= \sum _{i |n} \sum _{j|m} [gcd(i,j)=1]\] 这是因为nm的约数都可以表示为\(i \times \frac{m}{j}\)的形式,并且为了不重复算,要保证\(gcd(i,j)=1\

C语言 &#183; 约数个数

算法提高 约数个数 时间限制:1.0s   内存限制:512.0MB 输入一个正整数N,输出其约数的个数. 样例输入 12 样例输出 6 样例说明 12的约数包括:1,2,3,4,6,12.共6个. 1 #include<stdio.h> 2 int main(){ 3 int n; 4 int sum=0; 5 scanf("%d",&n); 6 if(n==0) return 0; 7 for(int i=1;i<=n/2;i++){ 8 if(n%i==

BZOJ 3994: [SDOI2015]约数个数和

3994: [SDOI2015]约数个数和 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 898  Solved: 619[Submit][Status][Discuss] Description 设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Output T行,每行一个整数,表示你所求的答案. Sample Input 2 7

【线性筛】【筛法求素数】【约数个数定理】URAL - 2070 - Interesting Numbers

素数必然符合题意. 对于合数,如若它是某个素数x的k次方(k为某个素数y减去1),一定不符合题意.只需找出这些数. 由约数个数定理,其他合数一定符合题意. 就从小到大枚举素数,然后把它的素数-1次方都排除即可. #include<cstdio> #include<cmath> using namespace std; #define MAXP 1000100 #define EPS 0.00000001 typedef long long ll; ll L,R; bool isNo

hdu1492(约数个数定理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1492 这里先讲一下约数个数定理: 对于正整数x,将其质因分解为 x = pow(p1, a) * pow*(p2, b) * pow(p3, c) * ... 则其约数个数为:num(x) = (a+1) * (b+1) * (c+1) *... 推导: 由约数定义可知p1^a1的约数有:p1^0, p1^1, p1^2......p1^a1 ,共(a1+1)个;同理p2^a2的约数有(a2+1)个