洛谷 P3927 SAC E#1 - 一道中档题 Factorial 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P3927 SAC E#1 - 一道中档题 Factorial 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://www.luogu.org/problem/show?pid=3927

题目背景

SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。

题目描述

SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

但是SOL菌太菜了于是请你帮忙。

输入输出格式

输入格式:

每组输入仅包含一行:两个整数n,k。

输出格式:

输出一个整数:n!在k进制下后缀0的个数。

输入输出样例

输入样例#1:
10 40
输出样例#1:
2

说明

对于20%的数据,n <= 1000000, k = 10

对于另外20%的数据,n <= 20, k <= 36

对于100%的数据,n <= 10^12,k <= 10^12

 

分析:

思路就是对n!和k分解质因数,然后对于每个n!和k共有的因数的指数求min。

看到有dalao用了RHO算法,萌新表示瑟瑟发抖。这题数据范围不大所以可以暴力水。

 

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<queue>
 6 
 7 const int MAXN = 1000002;
 8 inline void read(long long &x)
 9 {
10     char ch = getchar(),c = ch;x = 0;
11     while(ch < 0 || ch > 9) c = ch,ch = getchar();
12     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
13     if(c == -) x = -x;
14 }
15 
16 inline long long Min(long long a,long long b)
17 {return a<b?a:b;}
18 
19 bool isn[10000002];
20 long long prime[MAXN],num[MAXN],note[MAXN];
21 long long n,k,cnt,tot,sum,tmp,ans = 1LL*MAXN*MAXN;
22 
23 void makep()
24 {//线性筛 
25     isn[1] = true;
26     for(int i = 2;i <= 10000002;++ i)
27     {
28         if(!isn[i]) prime[++cnt] = i;
29         for(int j = 1;j <= cnt;++ j)
30         {
31             if(prime[j]*i > 10000002) break;
32             isn[prime[j]*i] = true;
33             if(i%prime[j] == 0) break;
34         }
35     }
36 }
37 
38 int main()
39 {
40     makep();
41     read(n),read(k);
42     for(int i = 1;i <= cnt && k != 1;++ i)
43     {//对k分解质因数 
44         if(prime[i] > n) break;
45         if(k%prime[i] == 0)
46         {
47             note[++tot] = prime[i];
48             while(k%prime[i] == 0){
49                 k /= prime[i];
50                 num[tot] ++;
51             }
52         }
53     }
54     for(int i = 1;i <= tot;++ i)
55     {//求出在n!中有多少个note[i],并更新ans
56         tmp = n,sum = 0;
57         while(tmp){
58             tmp /= note[i];
59             sum += tmp;
60         }
61 //        printf("%lld\n",sum/num[i]);
62         ans = Min(ans,sum/num[i]);
63 //        printf("%lld\n",ans);
64     }
65     if(ans == 1LL*MAXN*MAXN) printf("0\n");
66     else printf("%lld\n",ans);
67     return 0;
68 }

 

以上是关于洛谷 P3927 SAC E#1 - 一道中档题 Factorial 题解的主要内容,如果未能解决你的问题,请参考以下文章

LuoguP3927 SAC E#1 - 一道中档题 Factorial

SAC E#1 - 一道中档题 Factorial

Luogu_P3927_SAC E#1 - 一道中档题 Factorial

noip模拟赛 SAC E#1 - 一道中档题 Factorial

洛谷P3930SAC E#1 - 一道大水题 Knight

洛谷P3928 SAC E#1 - 一道简单题 Sequence2