题目描述
给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 109+7 取模。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个整数 ai。
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对 109+7 取模。
数据范围
1≤n≤100,
1≤ai≤2×109
样例
输入样例:
3
2
6
8
输出样例:
252
算法1
对于每一个括号的等比数列求和
可以用 t=1 while(a–) t=t*p-1
可以用求和公式 因为有/有% 且p是质数,也可以求逆元 用费马小定理
不必每个次方都用快速幂 时间复杂度大于前两种 见代码处
公式:
https://baike.baidu.com/item/%E7%BA%A6%E6%95%B0%E5%92%8C%E5%AE%9A%E7%90%86/3808428?fr=aladdin
C++ 代码
#include<iostream>
#include<unordered_map>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll p=1e9+7;
unordered_map<int,int> m;
ll qsm(int a,int b){
ll res=1;
while(b){
if(b&1) res=(res%p*a%p)%p;
b>>=1;
a=(a%p*a%p)%p;
}
return res%p;
}
void xs(ll n){
for(int i=2;i<=n/i;i++){
if(n==1)
break;
if(n%i==0){
while(n%i==0){
m[i]++;
n/=i;
}
}
}
if(n>1) m[n]++;
}
int main(){
int t;
cin>>t;
while(t--){
ll n;
cin>>n;
xs(n);
}
int t1=1;
for(auto t:m){
int p1=t.first,a=t.second;
// while(a--) t1=(t1*p1+1)%p; //时间复杂度O(n)
//但如果每一个指数都用快速幂 O(n*lgn)n:质数个数
//快速幂的时间复杂度O(lgn)
// res=(res*t1)%p;
t1=t1%p*(qsm(p1,a+1)-1)%p*qsm(p1-1,p-2)%p;//费马小定理,求p-1的逆元
//因为有/有%;
}
cout<<t1;
return 0;
}