首页 > 其他 > 详细

Luogu-P3807 【模板】卢卡斯定理

时间:2019-08-15 16:49:22      阅读:140      评论:0      收藏:0      [点我收藏+]

 

题目

题目链接

 

 

测试得分:  100

 技术分享图片

 

主要算法 :  Lucas定理,组合数,逆元

 

 

题干:

   Lucas板子

 

分析

  运用Lucas定理

    技术分享图片

  代码

   

#include<stdio.h>
#include<stdlib.h>
#define FORa(i,s,e) for(int i=s;i<=e;i++)
#define FORs(i,s,e) for(int i=s;i>=e;i--)
#define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),stdin)?EOF:*pa++

using namespace std;
char buf[100000],*pa,*pb;
inline int read();

const int N=1e5;
int k,n,m,p;
long long a[N+1],b[N+1];
long long Lucas(int x,int y)
{
    if(x<y) return 0;
    else if(x<p) return b[x]*a[y]*a[x-y]%p;
    else return Lucas(x/p,y/p)*Lucas(x%p,y%p)%p;
}
int main()
{
    k=read();
    while(k--)
    {
        n=read(),m=read(),p=read(); 
        a[0]=a[1]=b[0]=b[1]=1;
        FORa(i,2,n+m) b[i]=b[i-1]*i%p;//计算阶乘 
        FORa(i,2,n+m) a[i]=(p-p/i)*a[p%i]%p;//线性求逆元 
        FORa(i,2,n+m) a[i]=a[i-1]*a[i]%p;//阶乘逆元 
        printf("%lld\n",Lucas(n+m,m));
    }
    return 0;
}
inline int read()
{
    register char c(gc);register int f(1),x(0);
    while(c<0||c>9) f=c==-?-1:1,c=gc;
    while(c>=0&&c<=9) x=(x<<1)+(x<<3)+(c^48),c=gc;
    return x*f;
}

总结:

  1.预处理出逆元

 

 

技术分享图片

Luogu-P3807 【模板】卢卡斯定理

原文:https://www.cnblogs.com/SeanOcean/p/11358042.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!