扩展卢卡斯定理

时间:2019-03-16 16:43:31   收藏:0   阅读:61
技术图片
  1 //author Eterna
  2 #define Hello the_cruel_world!
  3 #pragma GCC optimize(2)
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<cstdio>
  7 #include<string>
  8 #include<cstring>
  9 #include<vector>
 10 #include<map>
 11 #include<set>
 12 #include<queue>
 13 #include<stack>
 14 #include<utility>
 15 #include<cmath>
 16 #include<climits>
 17 #include<deque>
 18 #include<functional>
 19 #include<complex>
 20 #include<numeric>
 21 #include<unordered_map>
 22 #define max(x,y) ((x)>(y)?(x):(y))
 23 #define min(x,y) ((x)<(y)?(x):(y))
 24 #define Pi acos(-1.0)
 25 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
 26 #define pb(x) push_back(x)
 27 #define lowbit(x) (x & -x)
 28 #define FRIN freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\in.txt", "r", stdin)
 29 #define FROUT freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\out.txt", "w", stdout)
 30 #define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
 31 #define outd(x) printf("%d\n", x)
 32 #define outld(x) printf("lld\n", x)
 33 #define il inline
 34 using namespace std;
 35 typedef long long ll;
 36 typedef unsigned long long ull;
 37 typedef pair<int, int> pii;
 38 const int maxn = 1e6;
 39 const int INF = 0x7fffffff;
 40 const int mod = 1e9 + 7;
 41 const double eps = 1e-7;
 42 inline int read_int() {
 43     char c;
 44     int ret = 0, sgn = 1;
 45     do { c = getchar(); } while ((c < 0 || c > 9) && c != -);
 46     if (c == -) sgn = -1; else ret = c - 0;
 47     while ((c = getchar()) >= 0 && c <= 9) ret = ret * 10 + (c - 0);
 48     return sgn * ret;
 49 }
 50 inline ll read_ll() {
 51     char c;
 52     ll ret = 0, sgn = 1;
 53     do { c = getchar(); } while ((c < 0 || c > 9) && c != -);
 54     if (c == -) sgn = -1; else ret = c - 0;
 55     while ((c = getchar()) >= 0 && c <= 9) ret = ret * 10 + (c - 0);
 56     return sgn * ret;
 57 }
 58 ll a[maxn + 5], c[maxn + 5];
 59 int cnt;
 60 ll n, m, p;
 61 il ll Quick_pow(ll base, ll index, const ll p) {
 62     ll ans = 1;
 63     while (index) {
 64         if (index & 1)ans = ans * base % p;
 65         base = base * base % p;
 66         index >>= 1;
 67     }
 68     return ans;
 69 }
 70 ll fac(const ll n, const ll p, const ll pk) {
 71     if (!n)return 1;
 72     ll ans = 1;
 73     for (int i = 1; i < pk; i++)if (i % p)ans = ans * i % pk;
 74     ans = Quick_pow(ans, n / pk, pk);
 75     for (int i = 1; i <= n % pk; i++)if (i % p)ans = ans * i % pk;
 76     return ans * fac(n / p, p, pk) % pk;
 77 }
 78 void ex_gcd(ll a, ll b, ll &x, ll &y, ll &d) {
 79     if (!b) { d = a, x = 1, y = 0; }
 80     else {
 81         ex_gcd(b, a % b, y, x, d);
 82         y -= x * (a / b);
 83     }
 84 }
 85 ll inv(ll t, ll p) {
 86     ll d, x, y;
 87     ex_gcd(t, p, x, y, d);
 88     return d == 1 ? (x % p + p) % p : -1;
 89 }
 90 ll C(const ll n, const ll m, const ll p, const ll pk) {
 91     if (n < m)return 0;
 92     ll f1 = fac(n, p, pk), f2 = fac(m, p, pk), f3 = fac(n - m, p, pk), cnt = 0;
 93     for (ll i = n; i; i /= p)cnt += i / p;
 94     for (ll i = m; i; i /= p)cnt -= i / p;
 95     for (ll i = n - m; i; i /= p)cnt -= i / p;
 96     return f1 * inv(f2, pk) % pk * inv(f3, pk) % pk * Quick_pow(p, cnt, pk) % pk;
 97 }
 98 inline ll CRT() {
 99     ll M = 1, ans = 0;
100     for (int i = 0; i < cnt; i++)M *= c[i];
101     for (int i = 0; i < cnt; i++)ans = (ans + a[i] * (M / c[i]) % M * inv(M / c[i], c[i]) % M) % M;
102     return ans;
103 }
104 ll exlucas(const ll n, const ll m, ll p) {
105     ll tmp = sqrt(p);
106     for (int i = 2; p > 1 && i <= tmp; i++) {
107         ll tmp = 1;
108         while (p % i == 0)
109             p /= i, tmp *= i;
110         if (tmp > 1)
111             a[cnt] = C(n, m, i, tmp), c[cnt++] = tmp;
112     }
113     if (p > 1)
114         a[cnt] = C(n, m, p, p), c[cnt++] = p;
115     return CRT();
116 }
117 int main()
118 {
119     cin >> n >> m >> p;
120     cout << exlucas(n, m, p) << endl;
121     return 0;
122 }
View Code

 

评论(0
0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!