LightOJ 1356 Aladdin and the Flying Carpet(唯一分解定理)

来源:互联网 发布:appreciate it 编辑:程序博客网 时间:2024/06/05 07:41

Aladdin and the Flying Carpet

解题思路:

题目大意:

给一对数字 a,b  ,a是一个长方形的面积,问有多少种整数的边的组合可以组成面积为a的长方形,要求最短的边不得小于b。

其实,就是求区间[b, a] 内的 a 的约数对的个数。满足c*d==a且c>=b且d>=b的c,d二元组对数,(c,d)和(d,c)属于同一种情况。

算法思想:

根据唯一分解定理,先将a唯一分解,则a的所有正约数的个数为num = (1 + a1) * (1 + a2) *...(1 + ai),这里的ai是素因子的指数,见唯一分解定理,因

为题目说了不会存在c==d的情况,因此num要除2,去掉重复情况,然后枚举小于b的a的约数,拿num减掉就可以了。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>using namespace std;typedef long long ll;int vis[1000005];vector<int> prime;void get_prime(){    memset(vis,0,sizeof(vis));    prime.clear();    for(int i = 2; i <= 1000000; i++){        int tt = 1000000/i;        for(int j = 2; j <= tt; j++)            vis[i*j] = 1;    }    for(int i = 2; i <= 1000000; i++){        if(!vis[i])            prime.push_back(i);    }}ll solve(ll n){    int l = prime.size();    ll ans = 1;    for(int i = 0; i < l && prime[i] <= sqrt(n*1.0); i++){        int t = 0;        while(n%prime[i] == 0){            t++;            n /= prime[i];        }        ans *= (t+1);    }    if(n > 1)        ans *= 2;    return ans;}int main(){    get_prime();    int T,t = 1;    scanf("%d",&T);    while(T--){        ll a,b;        scanf("%lld%lld",&a,&b);        if(a < b*b){             printf("Case %d: 0\n",t++);            continue;        }        ll ans = solve(a);        ans /= 2;        for(int i = 1; i < b; i++){            if(a%i == 0)                ans--;        }        printf("Case %d: %lld\n",t++,ans);    }    return 0;}


0 0
原创粉丝点击