Wannafly挑战赛25 因子 [数论]

一、题意

令 X = n!, 给定一大于1的正整数p 求一个k使得 p ^k | X 并且 p ^(k + 1) 不是X的因子

输入为两个数n, p (1e18>= n>= 10000 >= p >= 2)

二、分析

2.1前置知识:阶乘质因数分解

定理:在n!的标准分解式中,质因数p的指数h为

\[h = \left[ {\frac{n}{p}} \right] + \left[ {\frac{n}{{{p^2}}}} \right] + ... = \sum\limits_{r = 1}^\infty  {\left[ {\frac{n}{{{p^r}}}} \right]} \]

推论:n!可以由他的质因数表示为

\[n! = \prod\limits_{p \le n} {{p^{\sum {\left[ {\frac{n}{{{p^r}}}} \right]} }}} \]

2.2本题思路

由题意可得,p的质因数肯定是n!的质因数;所以首先将p做质因数分解,得到p的各个质因数的指数h,再对每一个p的质因数求其在n!中的指数H

那么题中所求的K肯定是每一对H/h的数值中的最小值

\[ans = \arg \min \frac{{{H_i}}}{{{h_i}}}\]

三、代码

 

 1 # include <iostream>
 2 # include <cstdio>
 3 using namespace std;
 4 const long long INF = 1e18+10;
 5 long long n,p;
 6 long long H(long long i)
 7 {
 8     long long res = 0;
 9     long long temp = n;
10     while(temp)
11     {
12         res += temp/i;
13         temp /= i;
14     }
15     return res;
16 }
17 void Solve()
18 {
19     long long ans = INF;
20     for(int i=2;i<=p;i++)
21     {
22         if(p%i == 0)
23         {
24             long long h = 0;
25             while(p%i==0)
26             {
27                 h++;
28                 p/=i;
29             }
30             ans = min(ans,H(i)/h);
31         }
32     }
33     printf("%lld\n",ans);    
34 }
35 int main()
36 {
37     while(scanf("%lld%lld",&n,&p)!=EOF)
38     {
39         Solve();
40     }
41     return 0;
42 }

 

posted @ 2018-10-05 17:11  cn_XuYang  阅读(168)  评论(0编辑  收藏  举报