zoukankan      html  css  js  c++  java
  • 拓展卢卡斯定理(伪)

    题目

    (a^{nchoose m}pmod{999999599})

    数据范围均为1e9

    思路

    转化

    首先观察到999999599是一个质数。根据费马小定理,我们只需要先求出 ({nchoose m}mod{999999598}),然后使用快速幂算法即可求得答案。

    卢卡斯定理?

    如果你还不知道卢卡斯定理是什么,可以阅读我的上一篇博文

    看到组合数取模这样的式子,自然想到用卢卡斯定理来求解。但是卢卡斯定理有一个限制:模数必须是质数。

    拓展卢卡斯定理?

    拓展卢卡斯定理是一个对卢卡斯定理的推广,可以解决模数不是质数的情况。关于它的详细资料可以参照卢卡斯定理 - OI Wiki

    正解

    然而这题不用拓展卢卡斯定理就能做啊Σ(っ °Д °;)っ或者说这是一个拓展卢卡斯定理的简化情况。

    我们对999999598进行质因数分解:

    嗯?正好四个质因数?那么我们可以使用如下方法求解:

    [egin{cases}Cequiv{nchoose m}pmod{2}\Cequiv{nchoose m}pmod{13}\Cequiv{nchoose m}pmod{5281}\Cequiv{nchoose m}pmod{7283}end{cases} ]

    也就是说,我们可以先求出({nchoose m}mod{2})({nchoose m}mod{13})({nchoose m}mod{5281})({nchoose m}mod{7283}),然后使用中国剩余定理来解决!

    代码

    注:代码中那些莫名其妙的常数是中国剩余定理的中间计算结果

    #define proname "silk"
    #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 a, n, m;
    
    ll fac[10000];
    
    ll pow(ll b, ll t, int p) {
      ll r = 1;
      for(; t; t>>=1, b = (b * b) % p) if (t & 1) r = (r * b) % p;
      return r;
    }
    
    ll C(ll n, ll k, int p) {
      if (k > n) return 0;
      return (fac[n] * pow(fac[k], p - 2, p) % p) * pow(fac[n - k], p - 2, p) % p;
    }
    
    ll lucas(ll n, ll k, ll p) {
      if (!k) return 1;
      return C(n % p, k % p, p) * lucas(n / p, k / p, p) % p;
    }
    
    ll calc(ll n, ll k, int p) {
      fac[0] = 1;
      for (int i = 1; i < p; ++i) fac[i] = (fac[i - 1] * i) % p;
      return lucas(n, k, p);
    }
    
    const int P = 999999599, M = P - 1;
    
    int main() {
      // freopen(proname".in", "r", stdin);
      // freopen(proname".out", "w", stdout);
      read(a);
      read(n);
      read(m);
      ll c1 = calc(n, m, 2);
      ll c2 = calc(n, m, 13);
      ll c3 = calc(n, m, 5281);
      ll c4 = calc(n, m, 7283);
      ll c = M / 2 * c1 % M;
      c += M / 13 * 8 * c2 % M;
      c %= M;
      c += M / 5281 * 4647 * c3 % M;
      c %= M;
      c += M / 7283 * 34 * c4 % M;
      c %= M;
      ll ans = pow(a, c, P);
      priln(ans);
    }
    
  • 相关阅读:
    MyBatis 框架系列之基础初识
    从零开始实现在线直播
    面试中关于Redis的问题看这篇就够了
    Spring Boot 中使用 MyBatis 整合 Druid 多数据源
    MyBatis的foreach语句详解
    小结:“服务器端跳转”和“客户端跳转”的区别
    Centos7.3安装vsftp服务
    Spring 注解@Value详解
    Spring中@Bean与@Configuration
    数据结构之LinkList
  • 原文地址:https://www.cnblogs.com/water-lift/p/12577514.html
Copyright © 2011-2022 走看看