• [洛谷P3807] 【模板】卢卡斯定理


    ({n+m choose n}mod p)

    卢卡斯(Lucas)定理

    [{n choose m}equiv{nmod p choose mmod p} imes{lfloor{nover p} floor choose lfloor{mover p} floor}pmod p ]

    证明(感谢Lance1ot)

    首先我们需要证明

    [{pchoose i}equiv{pover i}{p-1choose i-1}equiv 0pmod p,(1le ile p-1) ]

    [{pchoose i}={p!over i!(p-i)!}={pover i} {(p-1)!over(i-1)!(p-1-i+1)!} {pover i} {(p-1)!over(i-1)!(p-i)!}={pover i}{p-1choose i-1} ]

    得证。
    然后根据这种性质和二项式定理,我们马上得出

    [(1+x)^pequiv {pchoose0}1^p+{pchoose1}x^{2}+....+{pchoose p}x^pequiv {pchoose0}1^px^0+{pchoose p}1^0x^pequiv 1+x^ppmod p ]

    然后我们接下来要求证

    [{achoose b}equiv {a_0choose b_0}{a_1pchoose b_1p}{a_2p^2choose b_2p^2}dotspmod p ]

    (a=lp+r,b=sp+j)
    求证({achoose b}equiv {lchoose s}{rchoose j}pmod p)然后利用性质递归求解就可以了。
    继续从二次项定理出发

    [(1+x)^a=(1+x)^{lp} cdot (1+x)^r ]

    然后展开((1+x)^{lp})

    [(1+x)^{lp} equiv ((1+x)^p)^l equiv (1+x^p)^lpmod p ]

    [ herefore (1+x)^a equiv (1+x^p)^l(1+x)^rpmod p ]

    观察项(x^b)的系数

    [ecause {a^bchoose x^b}equiv{lchoose s}x^{sp}{rchoose j}x^jpmod p ]

    [ herefore {achoose b}x^b equiv {lchoose s}{rchoose j}x^bpmod p ]

    [ herefore {achoose b}equiv {lchoose s}{rchoose j} equiv {lfloor {aover p} floorchoose lfloor {bover p} floor}{amod pchoose bmod p}pmod p ]

    得证

    实现

    #include <cstdio>
    
    #define ll long long
    #define re register
    #define il inline
    #define gc getchar
    #define pc putchar
    
    template <class T>
    void read(T &x) {
      re bool f = 0;
      re char c = gc();
      while ((c < '0' || c > '9') && c != '-') c = gc();
      if (c == '-') f = 1, c = gc();
      x = 0;
      while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = gc();
      f && (x = -x);
    }
    
    template <class T>
    void print(T x) {
      if (x < 0) pc('-'), x = -x;
      if (x >= 10) print(x / 10);
      pc((x % 10) ^ 48);
    }
    
    template <class T>
    void prisp(T x) {
      print(x);
      pc(' ');
    }
    template <class T>
    void priln(T x) {
      print(x);
      pc('
    ');
    }
    
    ll fac[100005];
    
    ll pow(ll b, int t, ll p) {
      ll r;
      for (r = 1; t; t >>= 1, b = (b * b) % p)
        if (t & 1) r = (r * b) % p;
      return r;
    }
    
    ll C(ll n, ll m, ll p) {
      if (m > n) return 0;
      return (fac[n] * pow(fac[m], p - 2, p) % p) * pow(fac[n - m], p - 2, p) % p;
    }
    
    ll lucas(ll n, ll m, ll p) {
      if (m == 0) return 1;
      return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;
    }
    
    int main() {
      int t;
      read(t);
      while (t--) {
        ll n, m, p;
        read(n);
        read(m);
        read(p);
        fac[0] = 1;
        for (int i = 1; i <= p; ++i) fac[i] = (fac[i - 1] * i) % p;
        priln(lucas(n + m, m, p));
      }
    }
    
  • 相关阅读:
    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目
    jvm学习笔记二(减少GC开销的建议)
    jvm学习笔记一(垃圾回收算法)
    【转】 StringUtils中 isNotEmpty 和isNotBlank的区别
    单例模式
    工厂模式
    个人项目作业
    第一次作业-热身!
    第四单元总结
    第三单元总结
  • 原文地址:https://www.cnblogs.com/water-lift/p/12561427.html
Copyright © 2020-2023  润新知