GYM100633J. Ceizenpok’s formula 扩展lucas模板

J. Ceizenpok’s formula
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

Dr. Ceizenp'ok from planet i1c5l became famous across the whole Universe thanks to his recent discovery — the Ceizenpok’s formula. This formula has only three arguments: n, k and m, and its value is a number of k-combinations of a set of n modulo m.

While the whole Universe is trying to guess what the formula is useful for, we need to automate its calculation.

Input

Single line contains three integers n, k, m, separated with spaces (1 ≤ n ≤ 1018, 0 ≤ k ≤ n, 2 ≤ m ≤ 1 000 000).

Output

Write the formula value for given arguments n, k, m.

Examples
Input
2 1 3
Output
2
Input
4 2 5
Output
1
 
 
 
【题解】
裸的扩展lucas + CRT,推荐博文http://blog.csdn.net/clove_unique/article/details/54571216
因为特殊情况k = 0的时候,我以为是0,加了个特判,结果应该是1,不用特判。。。。。。。。。。卡了我半个晚上
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #include <map>
 9 #include <string> 
10 #include <cmath> 
11 #include <sstream>
12 #define min(a, b) ((a) < (b) ? (a) : (b))
13 #define max(a, b) ((a) > (b) ? (a) : (b))
14 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
15 template<class T>
16 inline void swap(T &a, T &b)
17 {
18     T tmp = a;a = b;b = tmp;
19 }
20 inline void read(long long &x)
21 {
22     x = 0;char ch = getchar(), c = ch;
23     while(ch < '0' || ch > '9') c = ch, ch = getchar();
24     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
25     if(c == '-') x = -x;
26 }
27 const long long INF = 0x3f3f3f3f;
28 
29 long long pow(long long a, long long b, long long mod)
30 {
31     long long r = 1, base = a % mod;
32     for(;b;b >>= 1)
33     {
34         if(b & 1) r *= base, r %= mod;
35         base *= base, base %= mod;
36     }
37     return r; 
38 }
39 void exgcd(long long a, long long b, long long &x, long long &y)
40 {
41     if(!b)x = 1, y = 0;
42     else exgcd(b, a%b, y, x), y -= (a / b) * x;
43 }
44 long long ni(long long x, long long mod)
45 {
46     long long inv, y; exgcd(x, mod, inv, y);
47     inv = (inv % mod + mod) % mod;
48     if(!inv) inv = mod;
49     return inv; 
50 }
51 int tiaoshi;
52 long long calc(long long n, long long p, long long pt)
53 {
54     if(n == 0) return 1;
55     long long ans = 1;
56     for(long long i = 1;i <= pt;++ i) if(i % p) ans *= i, ans %= pt;
57     ans = pow(ans, n/pt, pt);
58     for(long long i = 1;i <= n%pt;++ i) 
59         if(i % p) 
60             ans *= i, ans %= pt;
61     return ans * calc(n/p, p, pt) % pt;
62 }
63 long long C(long long n, long long m, long long p, long long pt)
64 {
65     if(n < m || n < 0 || m < 0) return 0;
66     long long cnt = 0;
67     for(long long i = n;i;i /= p) cnt += i/p;
68     for(long long i = m;i;i /= p) cnt -= i/p;
69     for(long long i = n - m;i;i /= p) cnt -= i/p;
70     return pow(p, cnt, pt) * calc(n, p, pt) % pt * ni(calc(m, p, pt), pt) % pt * ni(calc(n - m, p, pt), pt) % pt;
71 } 
72 long long exlucas(long long n, long long m, long long mod)
73 {
74     long long tmp2 = mod, ans = 0;
75     for(long long i = 2;i <= mod;++ i)
76         if(tmp2 % i == 0)
77         {
78             long long pt = 1;
79             while(tmp2 % i == 0)  tmp2 /= i, pt *= i;
80             long long tmp3 = C(n, m, i, pt);
81             ans += tmp3 * (mod/pt) % mod * ni(mod/pt, pt) % mod;
82             ans %= mod;
83         }
84     return ans;
85 }
86 long long n,m,p;
87 int main()
88 {
89     read(n), read(m), read(p);
90     printf("%lld", exlucas(n, m, p)); 
91     return 0;
92 }
GYM100633J

 

转载于:https://www.cnblogs.com/huibixiaoxing/p/8406941.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值