好久没发文章了.......不过粉丝还是一个没少......
今天来看两道超级恶心的数论题目!
No.1 约数个数
No.2 约数之和
先来看第一道:约数个数
题目描述
给定 n 个正整数 ai,请你输出这些数的乘积的约数个数,答案对 10^9+7 取模
输入格式
第一行包含整数 n
接下来 n 行,每行包含一个整数 ai
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对 10^9+7 取模
输入样例
3
2
6
8
输出样例
12
数据范围
对于全部的数据1≤n≤100,1≤ai≤2×10^9
思路:
用因数个数定理,注意取模(你不会想全乘起来吧?小心一分没有)
AC代码:
#include<bits/stdc++.h>
using namespace std;
map<int,int>cnt;
const int MOD=1e9+7;
signed main()
{
int n;
cin >> n;
while(n--)
{
int a;
cin >> a;
for(int i=2;1LL*i*i<=a;i++)
{
while(a%i==0)
{
cnt[i]++,a/=i;
}
}
if(a!=1)
{
cnt[a]++;
}
}
long long ans=1;
for(auto && i : cnt)
{
ans=(ans%MOD)*(i.second+1)%MOD;
}
cout<<ans;
return 0;
}
第二道:约数之和
题目描述
给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 10^9+7 取模
输入格式
第一行包含整数 n
接下来 n 行,每行包含一个整数 ai
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对 10^9+7 取模
输入样例
3
2
6
8
输出样例
252
数据范围
对于全部的数据1≤n≤100,1≤ai≤2×10^9
思路:
用因数和定理,注意取模
AC代码:
#include<bits/stdc++.h>
using namespace std;
map<int,int>cnt;
const int MOD=1e9+7;
signed main()
{
int n;
cin >> n;
while(n--)
{
int a;
cin >> a;
for(int i=2;1LL*i*i<=a;i++)
{
while(a%i==0)
{
cnt[i]++,a/=i;
}
}
if(a!=1)
{
cnt[a]++;
}
}
long long ans=1;
for(auto && i : cnt)
{
long long t=1,sum=0;
for(int j=0;j<=i.second;j++)
{
sum=(sum+t)%MOD;
t=t*i.first%MOD;
}
ans=ans*sum%MOD;
}
cout<<ans;
return 0;
}