【洛谷十月月测】 P3927 SAC E#1 - 一道中档题 Factorial

题目传送门:https://www.luogu.org/problemnew/show/P3927

题目大意:给你两个正整数n,k,求n!在k进制下末尾零的数量。

我们通过简单的数学分析,便可以发现,n!可以化为x*k^y(x,y∈N),而末尾零的数量,正是y。

经过进一步化简,n!=xd(k)1diyi,其中di为k的素因子,此处d(k)表示k的素因子个数,在已知d的情况下,求y并不复杂。

同时,我们也可以将k也化为这个格式,k=d(k)1diyi

通过进一步的归纳,我们发现:末尾零的数量为min(yi/yi)。此题我们只需要求出di,随后求出yiyi,最后简单计算即可得出答案。

考虑到k1012,如果用常规的方法进行分解质因数求出所有di显然不行,于是我们用pollard_rho进行分解质因数即可。

如果你不知道什么是pollard_rho,传送门:http://blog.csdn.net/maxichu/article/details/45459533

时间复杂度为O(k0.25log(n)d(k))

复制代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define L long long
 5 #include<algorithm>
 6 #include<map>
 7 using namespace std;
 8 L gcd(L x,L y){return y==0?x:gcd(y,x%y);}
 9 L mul(L x,L y,L MOD){
10     L ans=0;
11     while(y){
12         if(y&1) ans=(ans+x)%MOD;
13         y=y>>1; x=(x<<1)%MOD;
14     }
15     return ans;
16 }
17 bool pow(L x,L y,L MOD){
18     L ans=1;
19     while(y){
20         if(y&1) ans=mul(ans,x,MOD);
21         y=y>>1; x=mul(x,x,MOD);
22     }
23     return ans!=1;
24 }
25 bool check(L n){
26     if(n==2) return 1; if(n<2||n%2==0) return 0;
27     int t=20; while(t--) if(pow(1+rand()%(n-1),n-1,n)) return 0;
28     return 1;
29 }
30 L pollard_rho(L n,L c){
31     L x=1+rand()%(n-1),y=x,k=2;
32     for(int i=1;;i++){
33         x=(mul(x,x,n)+c)%n;
34         L d=gcd((y-x+n)%n,n);
35         if(d>1) return d;
36         if(x==y) return n;
37         if(i==k) y=x,k<<=1;
38     }
39 }
40 map<L,int> m;
41 void find(L n,L c){
42     if(n==1) return;
43     if(check(n)){m[n]++; return;}
44     L p=n; while(p>=n) p=pollard_rho(n,c--);
45     find(p,c); find(n/p,c);
46 }
47 L get(L n,L d){
48     L ans=0;
49     while(n) ans+=n/d,n=n/d;
50     return ans;
51 }
52 
53 int main(){
54     L n,k,minn=1e18; cin>>n>>k; find(k,2333333);
55     for(map<L,int>:: iterator it=m.begin();it!=m.end();it++){
56         L num=it->first,sum=it->second;
57         minn=min(minn,get(n,num)/sum);
58     }
59     cout<<minn<<endl;
60 }
复制代码

 

posted @   AlphaInf  阅读(165)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示