zoukankan      html  css  js  c++  java
  • LightOJ 1341 唯一分解定理

    Aladdin and the Flying Carpet
    Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu
    Appoint description: 

    Description

    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: ab(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

    1.有多少个约数:

    先分解质因数
    因数的次数分别是4,2,1

    所以约数的个数为(4+1)*(2+1)*(1+1)=5*3*2=30个

    eg:

    先分解质因数

    720=24*32*51

    因数的次数分别是4,2,1

    所以约数的个数为(4+1)*(2+1)*(1+1)=5*3*2=30个

    2.所有约数之和:

    2004的约数之和为:1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 ,2004  = 4704

    如何求一个数所有约数之和呢?

    首先,应用算术基本定理,化简为素数方幂的乘积。

    X = a1^k1 * a2^k2........an^kn

    X的所有素数之和可用公式(1+a1 + a1^2...a1^k1) * (1+a2 + a2^2...a2^k2) * .....(1+an + an^2...an^kn)表示

    如:

    2004 = 2^2  * 3  *167

    2004所有因子之和为(1  + 2 + 2^2) * (1 + 3) * ( 1 + 167) = 4704;

    程序实现的时候,可利用等比数列快速求1 + a1 + a1^2 + .....a1^n;

    思路:

    求出它的每个质因子的个数,然后用公式求出它的约数个数。如果b * b > a,那么值一定为0,其余部分可以枚举b,删除。但是我觉得枚举应该会挂掉,

    但是竟然没有挂。。

    /*
     * Author:  sweat122
     * Created Time:  2016/7/11 14:53:29
     * File Name: main.cpp
     */
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<time.h>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 1<<30
    #define MOD 1000000007
    #define ll long long
    #define lson l,m,rt<<1
    #define key_value ch[ch[root][1]][0]
    #define rson m+1,r,rt<<1|1
    #define pi acos(-1.0)
    using namespace std;
    const int MAXN = 1000050;
    int notprime[MAXN],prime[MAXN],cnt;
    ll a,b;
    void init(){
        cnt = 0;
        memset(prime,0,sizeof(prime));
        memset(notprime,0,sizeof(notprime));
        for(int i = 2; i < MAXN - 50; i++){
            if(!notprime[i]){
                prime[cnt++] = i;
            }
            for(int j = 0; j < cnt && 1LL * prime[j] * i < MAXN - 50; j++){
                notprime[prime[j] * i] = 1;
                if(i % prime[j] == 0) break;  
            }
        }
    }
    int main(){
        int t,Case = 0;
        init();
        scanf("%d",&t);
        while(t--){
            scanf("%lld%lld",&a,&b);
            ll ans = 1;
            ll x = a;
            for(int i = 0; i < cnt; i++){
                if(prime[i] > x)break;
                if(x % prime[i] == 0){
                    int num = 0;
                    while(x % prime[i] == 0){
                        num += 1;
                        x /= prime[i];
                    }
                    ans *= (num + 1);
                }
            }       
            if(x > 1) ans *= (1 + 1);
            ans /= 2;
            if(b * b > a){
                printf("Case %d: %lld
    ",++Case,0);
            } else{
                for(int i = 1; i < b; i++){
                    if(a % i == 0) ans -= 1;
                }   
                printf("Case %d: %lld
    ",++Case,ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    本地邮件系统的安装及配置
    通用性站点管理后台(Bee OPOA Platform) (2) 快速开发特性
    (转).NET Framework 自动内存管理机制深入剖析 (C#分析篇)
    通用性站点管理后台(Bee OPOA Platform) (3) MVC特性
    通用性站点管理后台(Bee OPOA Platform) (4) DAL
    通用性站点管理后台(Bee OPOA Platform) (1)
    【讨论】一个接口的世界
    Ubuntu Mono 初体验
    发现assembly的dll在temp里,AppDomain无法动态加载那个assembly
    熟知android模拟器的快捷键
  • 原文地址:https://www.cnblogs.com/sweat123/p/5660608.html
Copyright © 2011-2022 走看看