#6303. 水题
内存限制 10 MiB 时间限制:1000 ms 标准输入输出
题目描述
输入格式
输出格式
样例
数据范围与提示
解题思路:
由n!%kx=0可得:k^x必定是n!的一个约数,所以k中的质因数在$n!$肯定都存在,只是k中质因子的指数小于等于n!中的质因子的指数。
假如我们现在已经知道了k的每个质因数及其指数:P1C1 P2C2... PmCm
我们还知道n!的每个质因子及其指数:P1D1P2D2 ...PmDm
那么可以得到:
$C1*X_1<=D1$ $C_2*X_2<=D_2$ ... $C_m*X_m<=D_m$
可以知道$$min{ X_1 X_2 ...X_m }$$便是满足条件的最大的X。
现在将问题转换为求K和n!的质因数及其指数了。
对于K的质因数和指数我们可以在$sqrt{k}$的时间内求得,
而n!可以在$log{n}*sqrt{k}$的时间内得到。
#include<bits/stdc++.h> using namespace std; #define uint unsigned int #define re register int #define ll long long #define INF 0x3f3f3f3f #define maxn 5000009 #define maxm inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ll)(ch-'0');ch=getchar();} return x*f; } bool v[maxn]; ll prime[maxn]; ll n,m,k,ans,tot,cnt; void Prime() { for(int i=2;i<=3400000;i++) { if(!v[i]) prime[++cnt]=i; for(int j=1;j<=cnt&&i*prime[j]<=3400000;j++) { v[i*prime[j]]=1; if(i%prime[j]==0) break; } } } ll Cal(ll x,ll y) { if(x<y) return 0; return Cal(x/y,y)+x/y; } int main() { freopen("math.in","r",stdin); freopen("math.out","w",stdout); Prime(); while(scanf("%lld%lld",&n,&k)!=EOF) { ll ans=9e18; for(int i=1;prime[i]*prime[i]<=k;i++) { if(k%prime[i]==0) { cnt=0; while(k%prime[i]==0) ++cnt,k/=prime[i]; ans=min(ans,Cal(n,prime[i])/cnt); } } if(k!=1) ans=min(ans,Cal(n,k)); printf("%lld ",ans); } fclose(stdin); fclose(stdout); return 0; }