• 【数论】卢卡斯定理模板 洛谷P3807


    【数论】卢卡斯定理模板 洛谷P3807

    >>>>题目

    【题目】

    https://www.luogu.org/problemnew/show/P3807

    【输入格式】

    第一行一个整数T(Tle 10T10),表示数据组数

    第二行开始共T行,每行三个数n m p,意义如上

    【输出格式】

    共T行,每行一个整数表示答案。

    【输入样例】

    2
    1 2 5
    2 1 5

    【输出样例】

    3
    3

    >>>>分析

    emmmm模板题还是不用分析了吧

    卢卡斯定理解决的就是组合数C(n,m)中m,n太大的情况

    根据定理的内容,C(n,m)=C(n/p,m/p)*C(n%p,m%p)其中p是模数

    我们只需要不断递归求解C(n/p,m/p)就可以啦

    因为同余方程不满足两边同时除一个数,那么只能将除一个数转化成乘这个数在模数p意义下的逆元

    求逆元的方式有很多种,在我的另一个博客里面会有详细介绍φ(>ω<*) 

    #include<bits/stdc++.h>
    #define ll long long
    #define L I64d
    #define maxn 100005
    using namespace std;
    ll fac[2*maxn];
    int p,T;
    void init(int n,int m)//预处理阶乘
    {
        fac[0]=1;
        for(int i=1;i<=n+m;i++) fac[i]=fac[i-1]*i%p;
    }
    ll quickpow(ll x,ll y)
    {
        ll ans=1;
        while(y)
        {
            if(y&1) ans=ans*x%p;
            x=x*x%p;
            y=y>>1;
        }
        return ans%p;
    }
    ll C(ll m,ll n)
    {
        if(m>n) return 0;
        return fac[n]*quickpow(fac[m],p-2)%p*quickpow(fac[n-m],p-2);//费马小定理求逆元
    }
    ll lucas(ll m,ll n)
    {
        if(!m) return 1;
        return lucas(m/p,n/p)*C(m%p,n%p)%p;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d%d%d",&n,&m,&p);
            init();
            printf("%Ld
    ",lucas(m,n+m));
        }
        return 0;
    }
    /*
    2
    1 2 5
    2 1 5
    */

     完结撒花✿✿ヽ(°▽°)ノ✿

  • 相关阅读:
    FreeCAD框架解析
    Python源码的编译与加密
    centos 8及以上安装mysql 8.0
    浮点数运算丢失精度
    使用 Nginx 代理内网 GitLab 并确保 SSH / HTTP 克隆地址正确
    如何实现一个简易版的 Spring
    Spring 是如何造出一个 Bean 的
    从CPU缓存看缓存的套路
    Java 集合类 List 的那些坑
    react 项目中使用antd框架,对导航多层渲染
  • 原文地址:https://www.cnblogs.com/psyyyyyy/p/10498516.html
Copyright © 2020-2023  润新知