LightOJ 1341 Aladdin and the Flying Carpet(质因数分解、因子个数)

来源:互联网 发布:大淘客和淘宝客的区别 编辑:程序博客网 时间:2024/05/22 02:21

题目链接:
LightOJ 1341 Aladdin and the Flying Carpet
题意:
给出矩形的面积a,构造矩形的长和宽使得长宽都不小于b,矩形的面积恰好为a且长和宽不等。输出方案数。
分析:
根据:任何一个大于1的自然数n,若其不为素数则必可唯一的分解为有限个素数的乘积,即 n = p1^a1 * p2^a2 * p3^a3 * … * pk^ak,那么同时n的因子个数为num = ∏ (ai + 1)(1 <= i <= k)那么就可以知道a的因子个数num了,所以因子对数是num/2,然后遍历i:1–>b-1,如果i是a的因子那么num–,就好了。
可以先判断如果b > sqrt(a) 则方案数肯定为0.

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#include <bitset>#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;const int MAX_N = 1000010;int T, cases = 0, prime_cnt;ll a, b;int prime[MAX_N], vis[MAX_N];void GetPrime(){    prime_cnt = 0;    memset(vis, 0, sizeof(vis));    for(int i = 2; i < MAX_N; i++){        if(vis[i] == 0) { prime[prime_cnt++] = i; }        for(int j = 0; j < prime_cnt && i * prime[j] < MAX_N; j++){            vis[i * prime[j]] = 1;            if(i % prime[j] == 0) break;        }    }}int solve(){    ll n = a;    int ans = 1;    for(int i = 0; i < prime_cnt && prime[i] * prime[i] <= n; i++){        if(n % prime[i] == 0){            int num = 0;            while(n % prime[i] == 0){                num++;                n /= prime[i];            }            ans *= (num + 1);        }    }    if(n > 1) ans *= 2;    //ans = ( ans + 1) / 2; //矩形的长和宽不相同,也就是不考虑因子的平方是面积的情况,所以不用+1    ans /= 2;    for(int i = 1; i < b; i++){        if(a % i == 0) ans--;    }    return ans;}int main(){    GetPrime();    scanf("%d", &T);    while(T--){        scanf("%lld%lld", &a, &b);        ll m = (ll)sqrt((double)a + 0.5);        if(b > m) printf("Case %d: 0\n", ++cases);        else printf("Case %d: %d\n", ++cases, solve());    }    return 0;}
0 0