#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
bool isprime[N];
int prime[N];
int primeNumber;
void makeprime(int n)
{
memset(isprime, 1, sizeof isprime);
isprime[1] = 0;
for(int i = 2; i < n; ++i)
{
if(isprime[i]) for(int j = i+i; j < n; j += i)
isprime[j] = 0;
}
}
int getprime(int n)
{
int k = 0;
for(int i = 1; i < n; ++i)
{
if(isprime[i]) prime[k++] = i;
}
return k;
}
long long getpair(long long x)
{
//计算正约数个数方法:
//由这个数的素数的指数加一的和的乘积获得。
//正约数个数 ans=(a1+1)*(a2+1)*....*(an+1)
//a1,a2,...an为各个素数的指数
long long ans=1;
for(int i=0;i<primeNumber&&prime[i]<=sqrt(x+0.5);i++)
if(x%prime[i]==0)
{
int cnt=0;
while(x%prime[i]==0)
{
x/=prime[i];
cnt++;
}
ans*=(cnt+1);
}
if(x!=1)
ans*=2;
//x不是1的话,说明还没有满足将一个数分解成n个素数的次方乘积
//而这个数是一个素数,则直接*(1+1)
//例如10^12次方中还有10^11等级的素数。
return ans;
}
int main()
{
makeprime(N);
primeNumber=getprime(N);
//获取素数
int t,ca=1;
scanf("%d",&t);
while(t--)
{
long long a,b;
scanf("%lld%lld",&a,&b);
if(a<b*b)
printf("Case %d: 0\n",ca++);
//如果最短长度的平方,就是正方形都没有
//办法组成需要的面积,则没有组成矩形的可能
//不添加会超时
else
{
long long ans=getpair(a);
//获取到所有正约数的个数
ans/=2;
//如果存在两个相同因子组成a,向下取整后去掉这个因子,即去掉了
//正方形的地毯
for(int i=1;i<b;++i)
if(a%i==0)
ans--;
printf("Case %d: %lld\n",ca++,ans);
}
}
}
LightOJ - 1341
最新推荐文章于 2021-07-28 15:51:20 发布