题目链接:http://lightoj.com/volume_showproblem.php?problem=1236
分解质因数以后枚举完全包含某个质因子项的集合然后分别统计,除了全集以外,其余每种情况都会在枚举的时候多统计一次,那么得到的答案+1以后除以2以后便是本题答案
#include <stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
LL pri[1000000];
int siz=0;
bool is[10000010];
LL diiv[100];
LL ans=0;
int cnt[100],siz2;
void init(){
for(LL i=2;i<=10000000;i++){
if(!is[i])pri[++siz]=i;
for(int j=1;j<=siz&&i*pri[j]<10000000;j++){
is[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}
void diivid(LL n){
LL mx=sqrt(n);
memset(cnt,0,sizeof(cnt));
memset(diiv,0,sizeof(diiv));
for(int i=1;i<=siz;i++){
while(n%pri[i]==0){
if(diiv[cnt[0]]!=pri[i])diiv[++cnt[0]]=pri[i];
cnt[cnt[0]]++;
n/=pri[i];
}
if(pri[i]>mx||pri[i]>n)break;
}
if(n!=1){diiv[++cnt[0]]=n;cnt[cnt[0]]++;}
ans=0;
for(int i=0;i<(1<<cnt[0]);i++){
LL tt=1;
for(int j=0;j<cnt[0];j++){
if((1<<j)&i)tt*=(LL)(cnt[j+1]+1);
else tt*=(LL)cnt[j+1];
}
ans+=tt;
}
}
int main(void)
{
init();
int t,cas=0;
scanf("%d",&t);
while(t--){
LL n;
scanf("%lld",&n);
diivid(n);
printf("Case %d: %lld\n",++cas,(ans+1)>>1);
}
return 0;
}