LightOJ - 1341 合數分解

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 b denotes 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

這個題有兩個坑了我的地方,一個是a最大爲10^12,我當初以爲直接根號a暴力大於b的部分可解,結果他測試組數太多,GG

對於這個可以反着來,我們可以先求a的約數的個數,a=p1^e1*p2^e2*.......*pn^en,則約數個數爲(e1+1)*(e2+1)*......(en+1),

然後暴力小於b的約數的部分,兩者一減即可

第二個是這塊布不能爲正方形,搞得我開始瘋狂判 if(t^2=a)sum++; 然後瘋狂wa.......

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
const LL MAXN=1e6+233;
#define fi first
#define se second


LL prime[MAXN];
LL total;
bool isprime[MAXN];

void make()
{
    LL m=MAXN-3;
    memset(isprime,true,sizeof(isprime));
    isprime[1]=isprime[0]=false;
    total=0;
    for(int i=2;i<=MAXN;i++)
    {
        if(isprime[i])prime[++total]=i;
        for(int j=1;j<=total&&i*prime[j]<=m;j++)
        {
            isprime[prime[j]*i]=false;
            if(i%prime[j]==0)break;
        }
    }
}
LL n;
int main()
{
    LL a,b;
    LL T,cas=0;
    scanf("%d",&T);
    make();
    while(T--)
    {
        scanf("%lld%lld",&a,&b);
        printf("Case %d: ",++cas);
        if(b>(LL)sqrt(a)){puts("0");continue;}
        LL x=a,sum=1;
        for(int i=1;i<=total&&prime[i]*prime[i]<=x;i++)
        {
            LL y=0;
            while(x%prime[i]==0)
            {
                y++;
                x/=prime[i];
            }
            sum*=y+1;
        }
        if(x>1)sum*=2;
        LL res=0;
        for(int i=1;i<b;i++)if(a%i==0)res++;
        printf("%lld\n",(sum-res*2)/2);
    }
    return 0;
}

大概就是這樣了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章