Product
Accepts: 21
Submissions: 171
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
给n个数A1,A2....An,表示N=∏i=1niAi。求N所有约数之积。
输入描述
输入有多组数据. 每组数据第一行包含一个整数n.(1≤n≤105) 第二行n个整数A1,A2....An,保证不全为0.(0≤Ai≤105). 数据保证 ∑n≤500000.
输出描述
对于每组数据输出一行为答案对109+7取模的值.
输入样例
4 0 1 1 0 5 1 2 3 4 5
输出样例
36 473272463
本来以为自己不会做这道题,结果,哈哈哈。
就是把N分解成质数,再从里面取数构成约数。
最后推出的公式是(设质数是p1,p2,……pm,每个质数的幂数是bi,Q是(b1+1)*(b2+1)*……*(bn+1)):
p1^(Q*b1/2)*p2*(Q*b2/2)*……*pn(Q*bn/2) ,再加上费马小定理的优化,就可以过了。
以ac的代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 100010
#define MOD 1000000007
bool isprime[N];
int primenum[N];
int cou;
int primeid[N];
long long int numa[N];
void getprime(){
memset(isprime,true,sizeof(isprime));
isprime[0]=false;
isprime[1]=false;
cou=0;
for(int i=2;i<N;i++){
if(isprime[i]==true){
primenum[cou++]=i;
primeid[i]=cou-1;
}
for(int j=0;j<cou&&primenum[j]*i<N;j++){
isprime[i*primenum[j]]=false;
if(i%primenum[j]==0){
break;
}
}
}
return;
}
void add(int num,int a){
//printf("%d %d\n",num,a);
for(int j=0;j<cou&&primenum[j]*primenum[j]<=num;j++){
if(num%primenum[j]==0){
int tempcou=0;
while(num%primenum[j]==0){
tempcou++;
num=num/primenum[j];
}
numa[j]=numa[j]+a*tempcou;
}
}
if(num!=1){
numa[primeid[num]]+=a;
}
return;
}
long long int km(long long int x,long long int y){
long long int ans=1;
while(y){
if(y%2){
ans=ans*x%MOD;
}
y=y/2;
x=x*x%MOD;
}
return ans;
}
int main(){
int n;
int tempa;
getprime();
while(scanf("%d",&n)!=EOF){
memset(numa,0,sizeof(numa));
for(int i=1;i<=n;i++){
scanf("%d",&tempa);
add(i,tempa);//printf("wo shi da hao ren\n");
}
bool isodd=false;
long long int q=1;
for(int i=0;i<cou;i++){
if(numa[i]%2==1&&isodd==false){
q=q*((numa[i]+1)/2)%(MOD-1);
isodd=true;
}
else{
q=q*(numa[i]+1)%(MOD-1);
}
}
long long int ans=1;
if(isodd==false){//是==,而不是=,因为这个wr了,注意
for(int i=0;i<cou;i++){
ans=ans*km(primenum[i],q*(numa[i]/2)%(MOD-1))%MOD;
}
}
else{
for(int i=0;i<cou;i++){
ans=ans*km(primenum[i],q*numa[i]%(MOD-1))%MOD;
}
}
//printf("%lld\n",q);
printf("%lld\n",ans);
}
return 0;
}