数论(算术基本定理) - Aladdin and the Flying Carpet - LightOJ 1341

数论(算术基本定理) - Aladdin and the Flying Carpet - LightOJ 1341

题意:

a b a a b 给一对数字 a,b 。其中,a表示一个矩形的面积,想知道有多少种整数的边的组合可以组成面积为a的矩形,\\而且要求矩形的最短的边不得小于b

Input
T ( 4000 ) , . 第一行是一个整数 T (≤ 4000), 表示数据的组数.

: a , b ( 1 b a 1 0 12 ) a b . 每组数据包含两个整数: a,b (1 ≤ b ≤ a ≤ 10^{12}) 其中 a 表示矩形的面积 ,b为最小边.

Output

, . 对每组数据, 输出数据序号及可能的矩形的个数.

Sample Input

2
10 2
12 2

Sample Output

Case 1: 1
Case 2: 2

分析:

a b 本题本质上就是求,a的每一对约数中,满足较小的约数不小于b的约数对的数量。

a = P 1 a 1 P 2 a 2 . . . P k a k a 设a=P_1^{a_1}P_2^{a_2}...P_k^{a_k},通过算术基本定理,我们知道a的约数个数为:

D i v ( a ) = ( 1 + a 1 ) ( 1 + a 2 ) . . . ( 1 + a k ) Div(a)=(1+a_1)(1+a_2)...(1+a_k)

D i v ( a ) 2 [ 1 , b ) a c 那么约数对的数量为\frac{Div(a)}{2},然后我们统计[1,b)中,有多少个数是a的约数,假设有c个,

D i v ( a ) 2 c 那么最终答案就是\frac{Div(a)}{2}-c。

注意:

a a b > a 0 a至多有一个大于\sqrt{a}的约数,那么当b>\sqrt{a}时,我们可以直接判定答案为0。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>

#define ll long long

using namespace std;

const int N=1e6+10;

int primes[N],cnt;
bool st[N];
int ans;
int T;
ll a,b;

void get_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]*i<=n;j++)
        {
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }
}

int Div(ll a)
{
    ll res=1;
    for(int i=0;i<cnt;i++)
    {
        int p=primes[i];
        if(a%p==0)
        {
            ll t=0;
            while(a%p==0)
            {
                t++;
                a/=p;
            }
            res*=(t+1);
        }
        if(p>a) break;	//优化
        if(a==1) break;	//优化
    }
    if(a>1) res*=2;
    
    return res;
}

int main()
{
    get_prime(N-1);

    cin>>T;
    for(int t=1;t<=T;t++)
    {
        ans=0;
        
        cin>>a>>b;
        if(b<=sqrt(a)) 
        {
            int c=0;
            ans=Div(a)/2;
            for(int i=1;i<b;i++)
                if(a%i==0) 
                    c++;
            ans-=c;
        }

        printf("Case %d: %d\n",t,ans);
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107678959