Description
明明觉得hash是个好算法,代码短、效率高。某天,他碰到了一个求正方形个数的问题,于是很淡定地枚举对角线然后用hash判存在,妥妥的搞定,但是提交后却wa了几个点。仔细观察其hash函数为: h=x*y+x+y 。为了让明明知道这个函数存在什么问题,对于给出一个h值,请你来告诉他有多少对(x,y)满足上述式子(max(x,y)<=h;h,x,y都为非负整数)。
Input
多组测试数据,第一行为测试点的个数T,接下来每一行一个整数h,意义如上。
Output
一共T行,每行一个整数,分别表示有多少组(x,y)满足要其对应的h值。
Hint
[数据范围]
对于30%数据 h<=20,000 , T<=1000
对于100%数据 h<=100,000,000 , T<=10000;
Analysis
显然,对于 h=x*y+x+y 这个式子可以变换成 h+1=(x+1)*(y+1)
于是题目就变成了:对于式子 s=a*b 有多少组(a,b)满足要求。
这个时候只要对s进行质因数分解,然后统计每个质因子的个数
ans=ans*(count[i]+1);
最后一个要注意的地方:分解质因数的过程中可能最后会剩下一个很大的质数,超过了预处理出的素数上限。这时只需要特判一下分解完后,s是否等于1,不是的话将答案*2就行了。
Code
#include <stdio.h>
#include <cstring>
using namespace std;
int su[1240]={};
int a[10001];
int f[10001];
int main()
{
for (int i=2;i<=10000;i++)
if (!a[i])
{
for (int j=i;j<=10000;j+=i)
a[j]=1;
su[++su[0]]=i;
}
int t,n;
scanf("%d",&t);
while (t--)
{
bool flag;
memset(f,0,sizeof(f));
scanf("%d",&n);
n++;
do
{
flag=false;
for (int i=1;i<=su[0];i++)
if (n%su[i]==0)
{
flag=true;
f[su[i]]++;
n/=su[i];
break;
}
}while(flag);
int ans=1;
for (int i=1;i<=su[0];i++)
if (f[su[i]])
ans*=(f[su[i]]+1);
if (n!=1)
ans*=2;
printf("%d\n",ans);
}
return 0;
}