题目地址:http://lightoj.com/volume_showproblem.php?problem=1341
题目大意:长方形面积为a,在最小边大于等于b的情况下,有多少种。
题目是关于关于因子个数的,先用唯一分解定理求出a的因子数是多少,再用循环减去1~b-1中a的因子数。
注意要特判:b*b与a的关系,即可以控制时间复杂度在1e6,又可以防止出错。
图片来自于百度百科
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define maxn 1000009
int su[maxn],cnt,cas,factor[maxn];
bool is[maxn];
void prime( )
{
cnt=1;
memset(is,1,sizeof(is));
is[0]=is[1]=0;
for(int i=2;i<=maxn;i++)
{
if(is[i])
su[cnt++]=i;
for(int j=1;j<cnt&&i*su[j]<=maxn;j++)
is[su[j]*i]=0;
}
}
long long getprime(long long nn)
{
cas=0;
long long sum=1;
memset(factor,0,sizeof(factor));
for(int i=1;i<cnt&&su[i]*su[i]<=nn;i++)
{
while(nn%su[i]==0)
{
factor[cas]++;
nn=nn/su[i];
}
if(factor[cas]!=0)
cas++;
}
if(nn>1)
factor[cas++]=1;
for(int i=0;i<=cas;i++)
sum*=(1+factor[i]);
return sum;
}
int main()
{
int t,ans;
prime();
scanf("%d",&t);
long long a,b,sum;
ans=1;
while(t--)
{
scanf("%lld%lld",&a,&b);
if(b*b>a)///注意特判
{
printf("Case %d: %d\n",ans,0);
ans++;
continue;
}
sum=getprime(a);
sum=sum/2;
for(int i=1;i<b;i++)
{
if(a%i==0)
sum--;
}
printf("Case %d: %lld\n",ans,sum);
ans++;
}
return 0;
}