zoukankan      html  css  js  c++  java
  • CF#538(div 2) C. Trailing Loves (or L'oeufs?) 【经典数论 n!的素因子分解】

    任意门:http://codeforces.com/contest/1114/problem/C

    C. Trailing Loves (or L'oeufs?)

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output
    The number "zero" is called "love" (or "l'oeuf" to be precise, literally means "egg" in French), for example when denoting the zero score in a game of tennis.

    Aki is fond of numbers, especially those with trailing zeros. For example, the number 92009200 has two trailing zeros. Aki thinks the more trailing zero digits a number has, the prettier it is.

    However, Aki believes, that the number of trailing zeros of a number is not static, but depends on the base (radix) it is represented in. Thus, he considers a few scenarios with some numbers and bases. And now, since the numbers he used become quite bizarre, he asks you to help him to calculate the beauty of these numbers.

    Given two integers nn and bb (in decimal notation), your task is to calculate the number of trailing zero digits in the bb-ary (in the base/radix of bb) representation of n!n! (factorial of nn).

    Input

    The only line of the input contains two integers nn and bb (1n10181≤n≤1018, 2b10122≤b≤1012).

    Output

    Print an only integer — the number of trailing zero digits in the bb-ary representation of n!n!

    Examples
    input
    Copy
    6 9
    output
    Copy
    1
    input
    Copy
    38 11
    output
    Copy
    3
    input
    Copy
    5 2
    output
    Copy
    3
    input
    Copy
    5 10
    output
    Copy
    1
    Note

    In the first example, 6!(10)=720(10)=880(9)6!(10)=720(10)=880(9).

    In the third and fourth example, 5!(10)=120(10)=1111000(2)5!(10)=120(10)=1111000(2).

    The representation of the number xx in the bb-ary base is d1,d2,,dkd1,d2,…,dk if x=d1bk1+d2bk2++dkb0x=d1bk−1+d2bk−2+…+dkb0, where didi are integers and 0dib10≤di≤b−1. For example, the number 720720 from the first example is represented as 880(9)880(9) since 720=892+89+01720=8⋅92+8⋅9+0⋅1.

    You can read more about bases here.

    题意概括:

    求 n! 转化为 b 进制下末尾有多少个 0.

    解题思路:

    原题:swjtuOJ 2090

    这是一道很好的数论题。

    首先转换一下思路:

    要求 n! 在 b 进制下有多少个尾 0 就相当于 求 n! % (b^k) == 0 的最大 k。

    那么我们现在把 n! 看作一个数 A。问题就是 求 A % (b^k) == 0 的最大 k;

    我们知道有素数分解定理: b = p1^a1 * p2^a2 * p3^a3 ...;

    那么我们如果可以求得 A 里面 p1^b1 * p2^b2 * p3^b3 ...  的 b1, b2, b3...

    那么答案 ans = min(ans, ai/bi ) 了也就是要整除,首先要满足最小的那个能整除。

    (1)首先对 b 进行素因子分解,直接暴力(log b), 用一个数组离散化形成该素因子的编号和该素因子的幂的映射 或者 用map存储该素因子的幂,得到所有素因子以及素因子的幂 

    (2)对于每一个素因子p,计算对应的 A(即 n! ) 中素因子p的幂,两者相除取所有p幂的最小值就是对应的最大整数。

    这里求 n! 下 素因子 p 的幂 用累除法,因为存在推论:

    n! 下 p 的幂 = [ n/p ] + [ n/(p^2) ] + [ n/(p^3) ]  ...

     

    学习:

    https://blog.csdn.net/Wen_Yongqi/article/details/86976902

    AC code:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<vector>
     6 #include<queue>
     7 #include<cmath>
     8 #include<set>
     9 #include<map>
    10 #define INF 0x3f3f3f3f
    11 #define LL long long
    12 using namespace std;
    13 const int MAXN = 2e6+1000;
    14 LL N, B;
    15 vector<LL>prime;
    16 //LL num[MAXN];
    17 map<LL, int>mmp;
    18 void get_p(LL n)
    19 {
    20     LL len = sqrt((double)n);
    21     //printf("len %lld
    ", len);
    22     for(LL i = 2; i <= len; i++){
    23         if(n%i == 0){
    24             prime.push_back(i);
    25             while(n%i == 0){
    26                 n/=i;
    27                 //num[prime.size()-1]++;
    28                 mmp[i]++;
    29             }
    30         }
    31     }
    32     if(n != 1){
    33         prime.push_back(n);
    34 //        num[prime.size()-1]++;
    35         mmp[n]++;
    36     }
    37 }
    38 
    39 LL calc(LL n, LL p)
    40 {
    41     LL res = 0;
    42     while(n){
    43         res += n/p;
    44         n/=p;
    45         //puts("zjy");
    46     }
    47     return res;
    48 }
    49 
    50 int main()
    51 {
    52     LL sum = 1LL;
    53     scanf("%I64d %I64d", &N, &B);
    54     get_p(B);
    55     LL ans = (1LL<<62);
    56     for(LL i = 0; i < prime.size(); i++){
    57 //        ans = min(ans, calc(N, prime[i])/num[i]);
    58         //puts("zjy");
    59         ans = min(ans, calc(N, prime[i])/mmp[prime[i]]);
    60     }
    61 
    62     printf("%I64d
    ", ans);
    63     return 0;
    64 }
  • 相关阅读:
    Harvest of Apples (HDU多校第四场 B) (HDU 6333 ) 莫队 + 组合数 + 逆元
    BZOJ4383/LuoGuP3588 Pustynia/PUS 线段树建图优化
    初识splay
    nowcoder牛客wannafly挑战赛20
    初识树链剖分
    二维数据结构---线段树
    初识莫队——小Z的袜子
    kuangbin带我飞QAQ 并查集
    十个二分九个错?教你如何优雅地写二分查找
    Codeforces Round #436 (Div. 2) E. Fire(dp 记录路径)
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10361467.html
Copyright © 2011-2022 走看看