AtCoder Beginner Contest 280
D - Factorial and Multiple
数论
首先上这道题需要的数论知识:
n!的素因子分解中,n!=p1^a1 * p2^a2 * p3^a3 * ..... * pk^ak中
对于素因数pi,其对于的ai=n/pi+n/pi^2+n/pi^3+....直到n/pi^j==0为止
证明如下:
对于 n!= 1* 2 * 3* 4 * ...... * n
其中的数可以表达成: 1 2 3 ...pi ....2pi....n1pi....n,用变量num来记录n!钟表pi的个数
其中 n1*pi<=n && (n1+1)*pi>n
那么现在明显的pi个数为 n1, 且有 n1= n/pi ,所以 ans+=n1;
但是可能 n1>=pi,即会有 原来的序列可以表达成:
1 2 3...pi...2pi...3pi...pi*pi...2*pi*pi....3pi*pi.....n2*pi*pi...n
其中 n2*pi*pi<=n && (n2+1)*pi>n
其实这里的n2*pi*pi==上面的n1*pi,只是n1=n2*pi,那么在原来已经求得ans=n1的基础上,ans+=n1/pi
但是还可能n2>=pi,接下来的操作与上面相同,像递归一样
于是有:
对于素因数pi,其对于的ai=n/pi+n/pi^2+n/pi^3+....直到n/pi^j==0为止
题解:
然后再看题目
我们首先可以对K进行素数分解,O(sqrt(K))
然后,对n进行二分求解,即l=1,r=k;进行二分查找,对于mid=(l+r)>>1,看一下mid!的全部素因数的幂 是否>=K的全部素因数的幂
如果>=说明 mid! % K==0,否则不是
1 #include <iostream>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5 typedef long long ll;
6 const int N = 1e7;
7 ll k, t;
8 int pos = 0;
9 ll p[N], a[N];
10 bool check(ll mid)
11 {
12 for (int i = 1; i <= pos; i++)
13 {
14 ll n = mid, prime = p[i], num = 0;
15 while (n)
16 {
17 num += n / prime;
18 n /= prime;
19 }
20 if (num < a[i])
21 return false;
22 }
23 return true;
24 }
25 int main()
26 {
27 cin >> k;
28 ll l = 1, r = k, ans;
29 for (ll i = 2; i * i <= k; i++)
30 {
31 if (k % i == 0)
32 {
33 p[++pos] = i;
34 while (k % i == 0)
35 {
36 a[pos]++;
37 k /= i;
38 }
39 }
40 }
41 if (k > 1)
42 {
43 p[++pos] = k;
44 a[pos]++;
45 }
46 /* for (int i = 1; i <= pos; i++)
47 cout << p[i] << " " << a[i] << endl;
48 */
49 while (l <= r)
50 {
51 ll mid = (l + r) >> 1;
52 if (check(mid))
53 {
54 ans = mid;
55 r = mid - 1;
56 }
57 else
58 l = mid + 1;
59 }
60 cout << ans;
61 return 0;
62 }
本文作者:次林梦叶的小屋
本文链接:https://www.cnblogs.com/cilinmengye/p/16949992.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步