LigthOj 1341 Aladdin and the Flying Carpet ---唯一分解定理

Time limit   3000 ms

Memory limit   32768 kB

OS   Linux

Source   Problem Setter: Jane Alam Jan

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的所有因数对中大于等于b的因数对。这道题很容易知道是采用唯一分解定理,下面我们来了解一下唯一分解定理也叫算数基本定理:任何>1的整数都可以分解成有限个质数的乘积即n = P1^a1 * P2^a2 * …………*Pn^an (P1 < P2 < ……Pn);其中P为质因数,a为质因数的指数。有N的正因数的个数为

这道题只需要求正因数的个数即可,因为数据比较大,则必须采用素数打表的形式来分解质因子。对于b可以直接暴力枚举比b小的数且满足是a的因数的个数cnt,然后直接用分解质因子函数求出来的sum之除以2(因为是素数对)再减去cnt就可以得到答案。然后粘贴一篇写的挺好的有关唯一分解定理的博文:https://blog.csdn.net/qq_39439314/article/details/78270905

#include <iostream>
#include <string.h>
#include <math.h>
#define ll long long
#define maxn 1000010
using namespace std;
ll prime[maxn];
bool isprime[maxn];
int total;
void makeprime()//素数打表采用的线性筛选法
{
    total=0;
    memset(prime,0,sizeof(prime));
    memset(isprime,true,sizeof(isprime));
    isprime[1]=false;
    for(int i=2;i<=maxn;i++)
    {
        if(isprime[i])prime[total++]=i;
        for(int j=0;j<total&&i*prime[j]<=maxn;j++)
        {
            isprime[i*prime[j]]=false;
            if(i%prime[j]==0)break;
        }
    }
}
ll getzys(ll a)//分解质因数求因数的个数
{
    ll s=1,cont,i=0;
    if(a==0)return 0;
    while(prime[i]<a&&i<total)
    {
        cont=0;
        if(a%prime[i]==0){
            while(a%prime[i]==0){
                a/=prime[i];
                cont++;
            }
        }
        s*=1+cont;
        i++;
    }
    if(a>1)s*=2;
    return s;

}
int main()
{
    int t;
    ll a,b,sum,cnt;
    int k=0;
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    makeprime();
    cin>>t;
    while(t--)
    {
        cin>>a>>b;
        if(b>=sqrt(a))sum=0;
        else
        {
            ll cnt=0;
            for(ll i=1;i<b;i++)//暴力枚举小于b的因数的个数
                if(a%i==0)cnt++;
            sum=getzys(a)/2-cnt;//题目要求的是要求因数对所以除2
        }
        cout<<"Case "<<++k<<": "<<sum<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_41233888/article/details/81353257
今日推荐