ZOJ3557 How Many Sets II( Lucas定理)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition:
- T is a subset of S
- |T| = m
- T does not contain continuous numbers, that is to say x and x+1 can not both in T
Input
There are multiple cases, each contains 3 integers n ( 1 <= n <= 109 ), m ( 0 <= m <= 104, m <= n ) and p ( p is prime, 1 <= p <= 109 ) in one line seperated by a single space, proceed to the end of file.
Output
Output the total number mod p.
Sample Input
5 1 11 5 2 11
Sample Output
5 6
这是个组合数的基础问题了,从n个数中挑出m个数,要求不相邻。显然公式就是C(n-m+1,m),然后就可以直接用Lucas定理做了
1 /** 2 * code generated by JHelper 3 * More info: https://github.com/AlexeyDmitriev/JHelper 4 * @author xyiyy @https://github.com/xyiyy 5 */ 6 7 #include <iostream> 8 #include <fstream> 9 10 //##################### 11 //Author:fraud 12 //Blog: http://www.cnblogs.com/fraud/ 13 //##################### 14 //#pragma comment(linker, "/STACK:102400000,102400000") 15 #include <iostream> 16 #include <sstream> 17 #include <ios> 18 #include <iomanip> 19 #include <functional> 20 #include <algorithm> 21 #include <vector> 22 #include <string> 23 #include <list> 24 #include <queue> 25 #include <deque> 26 #include <stack> 27 #include <set> 28 #include <map> 29 #include <cstdio> 30 #include <cstdlib> 31 #include <cmath> 32 #include <cstring> 33 #include <climits> 34 #include <cctype> 35 36 using namespace std; 37 #define rep(X, N) for(int X=0;X<N;X++) 38 typedef long long ll; 39 40 // 41 // Created by xyiyy on 2015/8/15. 42 // 43 44 #ifndef ICPC_LUCAS_HPP 45 #define ICPC_LUCAS_HPP 46 47 // 48 // Created by xyiyy on 2015/8/5. 49 // 50 51 #ifndef ICPC_INV_HPP 52 #define ICPC_INV_HPP 53 typedef long long ll; 54 55 void extgcd(ll a, ll b, ll &d, ll &x, ll &y) { 56 if (!b) { 57 d = a; 58 x = 1; 59 y = 0; 60 } 61 else { 62 extgcd(b, a % b, d, y, x); 63 y -= x * (a / b); 64 } 65 } 66 67 ll inv(ll a, ll mod) { 68 ll x, y, d; 69 extgcd(a, mod, d, x, y); 70 return d == 1 ? (x % mod + mod) % mod : -1; 71 } 72 73 74 #endif //ICPC_INV_HPP 75 76 77 ll C(int n, int m, ll mod) { 78 if (n < m)return 0; 79 if (m == 0)return 1; 80 ll ret = 1; 81 rep(i, m) { 82 ret = ret * (n - i) % mod * inv(i + 1, mod) % mod; 83 } 84 return ret; 85 } 86 87 ll Lucas(ll n, ll m, ll mod) { 88 if (m == 0)return 1; 89 else return (C(n % mod, m % mod, mod) * Lucas(n / mod, m / mod, mod)) % mod; 90 } 91 92 93 #endif //ICPC_LUCAS_HPP 94 95 class TaskI { 96 public: 97 void solve(std::istream &in, std::ostream &out) { 98 int n, m, p; 99 while (in >> n >> m >> p) { 100 out << Lucas(n - m + 1, m, p) % p << endl; 101 } 102 } 103 }; 104 105 int main() { 106 std::ios::sync_with_stdio(false); 107 std::cin.tie(0); 108 TaskI solver; 109 std::istream &in(std::cin); 110 std::ostream &out(std::cout); 111 solver.solve(in, out); 112 return 0; 113 }