#include <vector>
namespace XDC{
typedef long long ll;
const int MOD = 1e9 + 7;
const int dirX[] = {1,-1,0,0};
const int dirY[] = {0,0,1,-1};
//杨辉三角求组合数
class YangHuiTriangle{
private:
std::vector< std::vector<ll> > angle;
int m_len;
public:
YangHuiTriangle(int len);
bool Init(int len);
ll C(int m, int n);
};
//求阶乘
extern ll GetFactorial(int n);
//求排列数
//n!/(n-m)!
extern ll P(int m, int n);
//求组合数
extern ll C(int m, int n);
//求次方
extern double Pow(double x, int n);
};
//using namespace XDC;
实现
#include "Xdc.h"
#include <algorithm>
namespace XDC{
YangHuiTriangle::YangHuiTriangle(int len)
{
Init(len);
}
bool YangHuiTriangle::Init(int len)
{
if (len <= 0) return false;
angle.clear();
m_len = len;
angle.assign(len, std::vector<ll>(len, 1));
for (int i = 2; i < len; ++i){
for (int j = 1; j < i; ++j){
angle[i][j] = angle[i-1][j-1] + angle[i-1][j];
}
}
return true;
}
ll YangHuiTriangle::C(int m, int n)
{
if (m < 0 || n < 0 || n >= m_len || m >= m_len) return -1;
if (m > n) return C(n, m);
if (m == 0 || m == n) return 1;
return angle[n][m];
}
//求阶乘
ll GetFactorial(int n){
if (n < 0) return -1;
if (n <= 1) return 1;
ll ret = 1;
for (ll i = 2; i <= n; ++i){
ret = ret * i;
}
return ret;
}
//求排列数
//n!/(n-m)!
ll P(int m, int n)
{
if (m < 0 || n < 0) return -1;
if (m > n) return P(n, m);
ll ret = 1;
for (ll i = n; i > n - m; --i){
ret = ret * i;
}
return ret;
}
//求组合数
//n!/ ((n-m)! * m!) 朴素的解法
ll _C(int m, int n){
if (m < 0 || n < 0) return -1;
if (m > n) return _C(n, m);
if (m > n / 2) return _C(n - m, n);
if (m == 0 || n == m) return 1;
ll _m = 1,_n = 1;
for (int i = 2; i <= m; ++i){
_m = _m * i;
}
for (int i = n; i>n - m; i--){
_n = _n * i;
}
return _n / _m;
}
//杨辉三角
ll _C_YangHui(int m, int n){
YangHuiTriangle angle(std::max(n,m));
return angle.C(m, n);
}
ll C(int m, int n){
if (std::max(m, n) <= 10) return _C(m, n);
return _C_YangHui(m, n);
}
double Pow(double x, int n)
{
if (n == 0) return 1;
double ret = 1.0,base = x;
while (n){
if (n & 1){
ret *= base;
}
base *= base;
n = n >> 1;
}
return ret;
}
};