1. 程式人生 > >Wannafly挑戰賽25 因子 數論

Wannafly挑戰賽25 因子 數論

using rod limit tdi void div mit 分析 正整數

一、題意

令 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 }

Wannafly挑戰賽25 因子 數論