/*
created by scarlyw
基础数学模板
*/
#include <bits/stdc++.h>
//最大公约数 & 最小公倍数
namespace gcd_lcm() {
//最大公约数 O(logn)
inline int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
//最小公倍数 (logn)
inline int lcm(int a, int b) {
return a * b / gcd(a, b);
}
}
//线筛
namespace s_seive {
//线筛质数 和 莫比乌斯函数(容斥函数) O(n)
int prime[MAXN], miu[MAXN];
int prime_cnt, n;
bool not_prime[MAXN];
inline void seive(int n) {
not_prime[1] = true, miu[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!not_prime[i]) prime[++prime_cnt] = i, miu[i] = -1;
for (int j = 1; j <= prime_cnt && prime[j] * i <= n; ++j) {
not_prime[i * prime[j]] = true;
if (i % prime[j] == 0) {
miu[i * prime[j]] = 0;
break;
}
miu[i * prime[j]] = -miu[i];
}
}
}
}
//质因子分解
namespace compose {
//暴力分解 O(sqrt(n))
inline void get_pactor() {
std::cin >> n, std::cout << n << "=";
for (int i = 2; i <= sqrt(n); ++i) {
while (n % i == 0) {
if (n == i) std::cout << i, exit(0);
else std::cout << i << "*", n /= i;
}
}
if (n != 1) std::cout << n;
}
}
//扩展欧几里得
namespace extand_gcd() {
//扩欧 O(logn)最后的(x % b + b) % b是满足ax = 1(mod b)的最小x
long long a, b, x, y, temp;
inline void ext_gcd(long long a, long long b) {
if (b == 0) x = 1, y = 0;
else ext_gcd(b, a % b), temp = x, x = y, y = temp - a / b * y;
}
}
//快速幂 & 快速乘
namespace mul_pow {
//O(log n)快速乘
long long n, m, mod;
inline long long mod_mul(long long a, long long b) {
long long ans = 0;
for (; b; b >>= 1, a = (a + a) % mod)
if (b & 1) ans = (ans + a) % mod;
return ans;
}
//O(1)快速乘
inline long long mod_mul(long long a, long long b) {
return (a * b - (long long)((long double)a / mod * b) * mod + mod) % mod;
}
//O(logn)快速幂
inline long long mod_pow(long long a, long long b) {
long long ans = 1;
for (; b; b >>= 1, a = mod_mul(a, a))
if (b & 1) ans = mod_mul(ans, a);
return ans;
}
}
//组合数
namespace combination {
//O(n ^ 2)组合数递推,方便取模
const int MAXN = 1000 + 10;
const int mod = 1000000000 + 7;
int c[MAXN][MAXN];
inline void get_c(int n) {
for (int i = 0; i <= n; ++i) c[i][0] = 1, c[i][i] = 1;
for (int i = 2; i <= n; ++i)
for (int j = 1; j < i; ++j)
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
//O(n)预处理阶乘和阶乘逆元,然后O(1)询问组合数
int fac[MAXN], inv[MAXN];
inline void get_c(int n) {
fac[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = (long long)fac[i - 1] * i % mod;
inv[n] = mod_pow(fac[n], mod - 2);
for (int i = n - 1; i >= 0; --i)
inv[i] = (long long)inv[i + 1] * (i + 1) % mod;
}
inline int c(int n, int m) {
return (long long)fac[n] * inv[m] % mod * inv[n - m] % mod;
}
}
//进制转换
namespace radix_change {
//十进制转任意进制
inline void radix_10_to_a(int num, int radix) {
static int sum[100], cnt;
while (num) sum[++cnt] = num % radix, num /= radix;
for (int i = cnt; i >= 1; --i)
if (sum[i] >= 10) std::cout << (char)(sum[i] + 'A' - 10);
else std::cout << sum[i];
return 0;
}
//任意进制转十进制
inline void radix_a_to_10(int radix, char *s) {
static int cnt, y;
cnt = strlen(s + 1);
for (int i = 1, y = 0; i <= cnt; ++i) {
if (isdigit(s[i])) y = y * radix + s[i] - '0';
else y = y * radix + s[i] - 'A' + 10;
}
std::cout << y;
}
}
//高精度
namespace big_integer {
const int MAXN = 200 + 10;
const int DIGIT = 1000000000;
//压9位的简单高精度类
struct big_integer {
long long a[MAXN];
int len;
//将big_integer初始化为long long or string代表的数字
big_integer(long long s = 0) {
len = 0, memset(a, 0, sizeof(a));
do a[++len] = s % DIGIT, s /= DIGIT;
while (s);
}
big_integer(char *s) {
len = 0, memset(a, 0, sizeof(a));
int s_len = strlen(s + 1);
long long t = 0, k = 1;
for (int i = s_len; i >= 1; --i) {
t = t + (s[i] ^ '0') * k, k = ((k << 2) + k << 1);
if (k == DIGIT) a[++len] = t, k = 1, t = 0;
}
if (t != 0) a[++len] = t;
}
//重载方括号b[i] = b.a[i];
inline long long & operator [] (const int &c) {
return a[c];
}
//重载方括号b[i] = b.a[i];
inline const long long & operator [] (const int &c) const {
return a[c];
}
//重载 <
inline bool operator < (const big_integer &b) const {
if (len != b.len) return len < b.len;
for (int i = len; i >= 1; --i)
if (a[i] != b[i]) return a[i] < b[i];
return false;
}
//高精 + 高精,重载 +,返回高精和
inline big_integer operator + (const big_integer &b) const {
big_integer c;
for (int i = 1; i <= len || i <= b.len; ++i)
c[i] += a[i] + b[i], c[i + 1] += c[i] / DIGIT, c[i] %= DIGIT;
c.len = std::max(len, b.len) + 2;
while (c[c.len] == 0) c.len--;
return (c.len) ? (0) : (c.len = 0), c;
}
//高精 * 高精,重载 *,返回高精积
inline big_integer operator * (const big_integer &b) const {
big_integer c;
for (int i = 1; i <= len; ++i)
for (int j = 1; j <= b.len; ++j) {
int pos = i + j - 1;
c[pos] += a[i] * b[j], c[pos + 1] += c[pos] / DIGIT;
c[pos] %= DIGIT;
}
c.len = len + b.len + 3;
while (c[c.len] == 0) c.len--;
return (c.len) ? (0) : (c.len = 1), c;
}
//高精 - 高精,重载 -,返回高精差,默认减数 > 被减数
inline big_integer operator - (const big_integer &b) const {
big_integer c;
for (int i = 1; i <= len; ++i)
c[i] += a[i] - b[i], (c[i] < 0) ? (c[i] += DIGIT, c[i + 1]--) : 0;
c.len = len;
while (c[c.len] == 0) c.len--;
return (c.len) ? (0) : (c.len = 1), c;
}
//高精 / 单精,重载 /,返回高精商
inline big_integer operator / (const long long b) const {
big_integer c;
long long t = 0;
for (int i = len; i >= 1; --i)
c[i] = (a[i] + t * DIGIT) / b, t = (a[i] + t * DIGIT) % b;
c.len = len;
while (c[c.len] == 0) c.len--;
return (c.len) ? (0) : (c.len = 1), c;
}
//高精 % 单精, 重载%,返回单精
inline big_integer operator % (const long long b) const {
return *this - *this / b * b;
}
//输出
inline void write() const {
printf("%lld", a[len]);
for (int i = len - 1; i >= 1; --i) printf("%09lld", a[i]);
}
} ;
//重载cin, cin >> (big_integer)a, 直接读入一个字符串,然后将a赋值为字符串
inline std::istream & operator >> (std::istream &a, big_integer &b) {
static char s[MAXN << 4];
scanf("%s", s + 1), b = s;
return a;
}
//重载cout, cout << (big_integer)b, 输出b,利用write()
inline std::ostream & operator << (std::ostream &a, const big_integer &b) {
b.write();
return a;
}
}
//高斯消元
namespace gauss {
const int MAXN = 100 + 10;
int n;
double f[MAXN][MAXN], ans[MAXN];
//f[i][j]表示第i个等式中第j个变量的系数,f[i][n + 1]表示第i个等式的值
inline void solve() {
for (int i = 1; i <= n; ++i) {
int pos = -1;
for (int j = i; j <= n; ++j)
if (f[j][i] != 0) {
pos = j;
break ;
}
std::swap(f[pos], f[i]);
for (int j = i + 1; j <= n; ++j) {
double t = f[j][i] / f[i][i];
for (int k = i; k <= n + 1; ++k)
f[j][k] -= t * f[i][k];
}
}
for (int i = n; i >= 1; --i) {
ans[i] = f[i][n + 1] / f[i][i];
for (int j = 1; j < i; ++j)
f[j][n + 1] -= f[j][i] * ans[i];
}
for (int i = 1; i <= n; ++i) std::cout << int(ans[i] + 0.5) << " ";
}
}
//矩阵乘法 & 矩阵快速幂
namespace matrix {
const int MAXN = 200 + 10;
const int mod = 1000000000 + 7;
//矩阵类
struct matrix {
int a[MAXN][MAXN];
int n;
matrix() {}
matrix(int n) : n(n) {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
a[i][j] = 0;
}
//重载 * , 矩阵乘法
inline matrix operator * (const matrix &b) const {
matrix ans(n);
for (int i = 1; i <= n; ++i)
for (int k = 1; k <= n; ++k)
for (int j = 1; j <= n; ++j)
ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j]) % mod;
return ans;
}
//重载 ^ ,矩阵快速幂
inline matrix operator ^ (int b) const {
matrix ans(n), a = *this;
for (int i = 1; i <= n; ++i) ans.a[i][i] = 1;
for (; b; b >>= 1, a = a * a)
if (b & 1) ans = ans * a;
return ans;
}
};
}
NOIP前 基础数学模板
最新推荐文章于 2018-11-07 10:56:00 发布