题目大意:有一个数a,求有多少组(n1,n2)n1*n2=a 且n1>=b&&n2>=b;
(n1,n2) (n2,n1)算一种;
思路:直接求[b,√a)有多少满足条件的数肯定是不行的。
唯一分解定理:
对于一个大于1正整数n可以分解质因数:
则n的正约数的个数就是
。
其中a1、a2、a3…ak是p1、p2、p3,…pk的指数。
因为a不可能出现(x,x)这组数,所以也f(n)/ 2 即为 答案
又因为pi都为素数,所以可以打一个素数表来优化时间
代码:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
long long a,b;
const int maxn=1000047;
long long cnt=1;
int prim[maxn],p[maxn];
int k = 0;
void find_prim()
{
k = 0;
for(int i = 2; i < maxn; i++)
{
if(!p[i])
{
prim[k++] = i;
for(int j = i+i; j < maxn; j+=i)
{
p[j] = 1;
}
}
}
}
void get(){
cnt=1;
int j=0;
for(int i=0;prim[i]<=a/prim[i];i++){ //prim[i]<a&&i<k用这个的话耗时比较大
if(a%prim[i]==0){
j=0;
while(a%prim[i]==0){
a/=prim[i];
j++;
}
cnt*=(j+1);
}
}
if(a>1) cnt*=2;
cnt/=2;
}
int main()
{
find_prim();
int t;
scanf("%d",&t);
for(int k=1;k<=t;k++){
scanf("%lld%lld",&a,&b);
long long c=a;
if(b*b>=a) {
cnt=0;
}
else {
get();
for(int i=1;i<b;i++){
if(c%i==0) cnt--;
}
}
printf("Case %d: %lld\n",k,cnt);
}
return 0;
}