LightOJ

来源:互联网 发布:扬子石化SAP软件 编辑:程序博客网 时间:2024/06/06 18:03

It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we are concerned about the first mystery.

Aladdin was about to enter to a magical cave, led by the evil sorcerer who disguised himself as Aladdin's uncle, found a strange magical flying carpet at the entrance. There were some strange creatures guarding the entrance of the cave. Aladdin could run, but he knew that there was a high chance of getting caught. So, he decided to use the magical flying carpet. The carpet was rectangular shaped, but not square shaped. Aladdin took the carpet and with the help of it he passed the entrance.

Now you are given the area of the carpet and the length of the minimum possible side of the carpet, your task is to find how many types of carpets are possible. For example, the area of the carpet 12, and the minimum possible side of the carpet is 2, then there can be two types of carpets and their sides are: {2, 6} and {3, 4}.

Input

Input starts with an integer T (≤ 4000), denoting the number of test cases.

Each case starts with a line containing two integers: a b (1 ≤ b ≤ a ≤ 1012) where a denotes the area of the carpet and bdenotes the minimum possible side of the carpet.

Output

For each case, print the case number and the number of possible carpets.

Sample Input

2

10 2

12 2

Sample Output

Case 1: 1

Case 2: 2


【知识点】唯一分解定理

1.有多少个约数

先分解质因数
因数的次数分别是4,2,1

所以约数的个数为(4+1)*(2+1)*(1+1)=5*3*2=30个

例:

先分解质因数

720=24*32*51

因数的次数分别是4,2,1

所以约数的个数为(4+1)*(2+1)*(1+1)=5*3*2=30个


2.所有约数之和:

2004的约数之和为:1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 ,2004  = 4704

如何求一个数所有约数之和呢?

首先,应用算术基本定理,化简为素数方幂的乘积。

X = a1^k1 * a2^k2........an^kn

X的所有素数之和可用公式(1+a1 + a1^2...a1^k1) * (1+a2 + a2^2...a2^k2) * .....(1+an + an^2...an^kn)表示

如:

2004 = 2^2  * 3  *167

2004所有因子之和为(1  + 2 + 2^2) * (1 + 3) * ( 1 + 167) = 4704;

程序实现的时候,可利用等比数列快速求1 + a1 + a1^2 + .....a1^n;

思路:根据知识点部分,先进行素数打表(分解n的质因数会超时),用p数组记录下来,根据打表后的素数算多少次方,然后代入公式,最后暴力m就可以(优化一下,注意m*m和n的大小);本题坑点就是,先不要直接分解质因子,把素数打表;

#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define max_n 1000050typedef long long LL;using namespace std;LL p[max_n],a[max_n]; //注意p数组大小,虽然用不了,但init里可能会RE int k=0;//void getp(LL n)  打表,不然超时,这么低也超QAQ //{//k=0;//for(int i=2;i*i<=n;i++)//{//if(n%i==0)//{//p[k++]=i;//while(n%i==0) n/=i;//}//}//if(n>1) p[k++]=n;//}void init(){memset(p,0,sizeof(p));memset(a,0,sizeof(a));a[0]=a[1]=1;for(int i=2;i*i<=max_n-5;i++){if(!a[i]){for(int j=i+i;j<=max_n-5;j+=i)a[j]=1;}}for(int i=1;i<=max_n-5;i++){if(!a[i])p[k++]=i;}}LL nop(LL n){LL ans=1;for(int i=0;i<k;i++){if(p[i]>n) break;LL res=0;while(n%p[i]==0){res++;n/=p[i];}ans=ans*(res+1);}if(n>1) ans*=2;//注意这一步return ans;}int main(){init();LL n,m,t;scanf("%lld",&t);while(t--){LL num=0,ans,res=0;scanf("%lld %lld",&n,&m);ans=nop(n)/2;//printf("%lld\n",ans);if(m*m>n) ans=0;else{num=0;for(int i=1;i<m;i++){if(n%i==0) num++;}ans-=num;}static int p=1;printf("Case %d: %lld\n",p++,ans);}return 0;} 


原创粉丝点击