您的位置:首页 > 其它

ZOJ3557 How Many Sets II( Lucas定理)

2015-08-16 01:09 459 查看
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud

How Many Sets IITime Limit: 2 Seconds Memory Limit: 65536 KB
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定理做了

/**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper * @author xyiyy @https://github.com/xyiyy
*/

#include <iostream>
#include <fstream>

//#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/ //#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>

using namespace std;
#define rep(X, N) for(int X=0;X<N;X++)
typedef long long ll;

//
// Created by xyiyy on 2015/8/15.
//

#ifndef ICPC_LUCAS_HPP
#define ICPC_LUCAS_HPP

//
// Created by xyiyy on 2015/8/5.
//

#ifndef ICPC_INV_HPP
#define ICPC_INV_HPP
typedef long long ll;

void extgcd(ll a, ll b, ll &d, ll &x, ll &y) {
if (!b) {
d = a;
x = 1;
y = 0;
}
else {
extgcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}

ll inv(ll a, ll mod) {
ll x, y, d;
extgcd(a, mod, d, x, y);
return d == 1 ? (x % mod + mod) % mod : -1;
}

#endif //ICPC_INV_HPP

ll C(int n, int m, ll mod) {
if (n < m)return 0;
if (m == 0)return 1;
ll ret = 1;
rep(i, m) {
ret = ret * (n - i) % mod * inv(i + 1, mod) % mod;
}
return ret;
}

ll Lucas(ll n, ll m, ll mod) {
if (m == 0)return 1;
else return (C(n % mod, m % mod, mod) * Lucas(n / mod, m / mod, mod)) % mod;
}

#endif //ICPC_LUCAS_HPP

class TaskI {
public:
void solve(std::istream &in, std::ostream &out) {
int n, m, p;
while (in >> n >> m >> p) {
out << Lucas(n - m + 1, m, p) % p << endl;
}
}
};

int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TaskI solver;
std::istream &in(std::cin);
std::ostream &out(std::cout);
solver.solve(in, out);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: