lucas定理+费马小定理方法求逆元-HDU3944
来源:互联网 发布:网络歌手袁晓婕诈骗 编辑:程序博客网 时间:2024/06/05 12:03
https://vj.xtuacm.cf/contest/view.action?cid=59#problem/E
这题目用的线性方法求逆元要记住
题目的意思是说,在杨辉三角上找一条路径,每次必须往下走一行,使得这个路径上所有数字的总和最小,输出取模值。
这里对于组合数有一个变换。C(n-1,k-1)+C(n-1,k)=C(n,k)
同时,仔细观察杨辉三角就知道,对于每行,从左至中间都是递增的,同时又根据对称性,把所有大于每行中点的点对称到左边来。
这样从目标点出发,每次都往左上方走,然后,走到第0列的时候就往上一直走(全为1),即最小值。
这样其结果可以表示为:
C(n,k)+C(n-1,k-1)+……+C(n-k+1,1)+C(n-k,0)+C(n-k-1,0)+……C(0,0);
注意观察这个式子和我开始列出来的那个公式,如果我们把C(n-k,0)写成C(n-k+1,0)(为什么?因为都是1呗!),
这样,上面式子昨天那一段,可以从尾到头依次合并,最终合并为C(n+1,k),ORZ。所以这里只要求一次组合数就可以了呢。
但是问题又来了,题目明确说了有100000组数据,而一般用Lucas定理求组合数的时间复杂度和P同级。这里P<=10000。所以这样做就会超时呢。
定义一个数组,所有小于10000的数的阶乘对所有小于10000的的素数进行取模,这样到lucas定理计算的时候就可以直接用。同时对逆元进行打表处理。
#include <iostream>#include <cstdio>#include <cmath>using namespace std;int mod;int prime[1500],shu[10005],cnt=0;//质数打表int fac[10005][10005],inv[10005][10005];//阶乘打表,逆元打表void init1()//质数打表{ for(int i=2;i<=10000;i++) { if(!shu[i]) { prime[cnt++]=i; for(int j=i*2;j<=10000;j+=i) shu[j]=1; } }}int quick_pow(int n,int m,int k){ int ans=1; while(m) { if(m&1)ans=(ans*n)%k; m>>=1; n=(n*n)%k; } return ans;}void init2()//预处理阶乘表和逆元表{ for(int i=0;i<cnt;i++) { fac[prime[i]][0]=inv[prime[i]][0]=1; for(int j=1;j<=prime[i];j++) { fac[prime[i]][j]=(fac[prime[i]][j-1]*j)%prime[i]; inv[prime[i]][j]=quick_pow(fac[prime[i]][j],prime[i]-2,prime[i]); //费马小定理求逆元 } }}int C(int m,int n)//组合数{ if(n>m)return 0; return fac[mod][m]*(inv[mod][n]*inv[mod][m-n]%mod)%mod;}int lucas(int m,int n)//lucas定理{ if(!n)return 1; else return C(m%mod,n%mod)*lucas(m/mod,n/mod);}int main(){ int k,n,p; int ca=1; init1(); init2(); while(~scanf("%d%d%d",&n,&k,&p)) { mod=p; if(k>n/2) k=n-k; int s=(lucas(n+1,k)+n-k)%mod; printf("Case #%d: %d\n",ca++,s); } return 0;}
阅读全文
0 0
- lucas定理+费马小定理方法求逆元-HDU3944
- hdu3944(Lucas定理+预处理)
- hdu3944(Lucas定理+预处理)
- hdu3944 lucas定理+阶乘预处理
- HDU3944 DP? (LUCAS定理+阶乘预处理)
- HDU3944-DP?(帕斯卡公式+Lucas定理)
- hdu3944 DP? (lucas定理+预处理)
- HDU3944 DP?(大组合数取模:lucas定理)
- [HDU3944]DP? (组合数学Lucas定理)
- Lucas 定理
- Lucas 定理
- lucas定理
- Lucas定理
- Lucas 定理
- Lucas 定理
- Lucas 定理
- Lucas 定理
- Lucas定理
- C++学习笔记之类
- (4)全局变量、局部变量、常见对象(Object、String)、自定义方法
- Android之MPAndroidChart库——双柱状图,X轴显示汉字
- SLAM学习——建图问题(一)
- 2.1.22—线性表—Candy
- lucas定理+费马小定理方法求逆元-HDU3944
- springmvc生成excel表
- 转载:Entity Framework 入门4篇连载
- 卷积神经网络CNN之实践样例
- MySQL如何设置自动增长列
- Shader实例:边缘发光和描边
- excel解析
- Hello JPEG 2000
- Trafodion 更新统计信息数据收集