音无结弦之时,天使跃动之心。立于浮华之世,奏响天籁之音。.|

次林梦叶

园龄:3年3个月粉丝:22关注:3

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 中国大陆许可协议进行许可。

posted @   次林梦叶  阅读(81)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起