题目 :
任何一个正整数N,我们可以很容易的找出N的所有因子,N1,N2,N3...,Nk,称N一共有k个因子(包含1和N本身)。
求出N所有因子的因子个数(如N1可能包含n1个因子(包含1和N1本身),N2可能包含n2个因子,...,Nk可能包含nk个因子),然后计算出S的值:
因为要求出N的因子个数,我们从素数开始讨论。N=1时只有一个因子1,对于任意一个质数p,只有1和p两个因子,所以 ,而对于一个质数的幂 ,它的因子分别是 一共k个,因子的因子数分别是1,2,3,...,k+1个,因此:
如果N有两个不同的素因子p1和p2,这时不妨设 ,这时可以把N的因子按照和 的最大公约数来分成k2+1 类,显然每一类的数目都是一样的。注意到一个事实 ,我们很容易得到:
代码如下:
#include <cstdio>
#include <cstring>
#define MEM(a,x) memset(a,x,sizeof(a))
typedef long long llt ;
using namespace std;
// 线性筛素数
const int SIZE = 1000000;
bool isComp[SIZE] = {false};
int P[SIZE] = {0};
int PCnt = 0;
void sieve(){
for(int i=2;i<SIZE;++i){
if ( !isComp[i] ) P[PCnt++] = i;
for(int j=0;j<PCnt&&i*P[j]<SIZE;++j){
isComp[i*P[j]] = true;
if ( 0 == i % P[j] ) break;
}
}
}
//得到质因数
int factor[1000];
int FCnt;
void GetFct( int n ){
for (int i = 0;P[i] * P[i] <= n && i < PCnt;++i ){
if ( n <= 1 ) break;
if ( n % P[i] == 0 ){
FCnt++;
while ( n % P[i] == 0 ){
factor[FCnt]++;
n /= P[i];
}
}
}
if ( n > 1 )
factor[++FCnt]++;
}
//预处理
const int SIZE_THIRD = 10000;
int third[SIZE_THIRD] = {0};
int sumthird[SIZE_THIRD] = {0};
void init(){
MEM(sumthird,0);
for (int i = 1;i < SIZE_THIRD;++i){
third[i] = i*i*i;
sumthird[i] = third[i] + sumthird[i-1];
}
}
int solve(int n ){
GetFct(n);
int ans=0;
int last = 1;
for (int i = 0;i <= FCnt;++i ){
int tmp = sumthird[factor[i]+1];
last = last * tmp;
}
return last;
}
int main(){
//freopen("cout.txt", "w", stdout);
sieve();
init();
//while(1);
int n,t;
//t = 100000;
scanf("%d",&t);
while ( t-- ){
scanf("%d",&n);
//n =( rand() * 11011)%INT_MAX;
FCnt = 0;
MEM(factor,0);
int ans = solve(n);
printf("%d\n" , ans);
}
return 0;
}