CSP数论模板

  • 快速幂与乘法运算
inline ll add(ll a, ll b) { return (a += b) >= mod ? a - mod : a; }
inline ll sub(ll a, ll b) { return (a -= b) < 0 ? a + mod : a; }
inline ll mul(ll a, ll b) { return a * b % mod; }

inline void Add(ll &a, ll b) { a = add(a, b); }
inline void Sub(ll &a, ll b) { a = sub(a, b); }
inline void Mul(ll &a, ll b) { a = mul(a, b); }

inline ll quickpow(ll a, ll b) {
	ll re = 1;
	while(b) {
		if(b & 1)	Mul(re, a);
		b >>= 1;
		Mul(a, a);
	}
	return re;
}

inline ll greatmul(ll a, ll b) { return add(sub(a * b, (ll)(((long double)a * b + 0.5) / mod) * mod), mod); }
inline void GreatMul(ll &a, ll b) { a = greatmul(a, b); }

inline ll Quickpow(ll a, ll b) {
	ll re = 1;
	while(b) {
		if(b & 1)	GreatMul(re, a);
		b >>= 1;
		GreatMul(a, a);
	}
	return re;
}
  • 后面还能加上一句
inline ll get_inv(ll x) { return quickpow(x, mod - 2); }//费马小定理求逆元
  • 组合数学模板
ll fac[N + 10], inv[N + 10], c[M + 10][M + 10];
inline void input() {
	fac[0] = 1;
	for(int i = 1; i <= N; ++i)	fac[i] = mul(fac[i - 1], i);
	inv[N] = get_inv(fac[N]);
	for(int i = N; i >= 1; --i)	inv[i - 1] = mul(inv[i], i);
	c[0][0] = 1;
	for(int i = 1; i <= M; ++i) {
		c[i][0] = 1;
		for(int j = 1; j <= i; ++j)
			c[i][j] = add(c[i - 1][j], c[i - 1][j - 1]);
	}
}

inline ll C(ll n, ll m) {
	if(n < m || n < 0 || m < 0)	return 0;
	return mul(fac[n], mul(inv[m], inv[n - m]));
}
  • 解丢番图方程
inline ll exgcd(ll a, ll b, ll &x, ll &y) {
	if(!b) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = exgcd(b, a % b, x, y);
	ll z = x;
	x = y;
	y = z - (a / b) * y;
	return d;
}
  • 一行gcd
inline ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
  • 线性筛
int v[N + 10], prime[(N + 10) / 10], phi[N], m;
inline void euler(int n) {
	memset(v, 0, sizeof(v));
	m = 0;
	for(int i = 2; i <= n; ++i) {
		if(!v[i]) {
			v[i] = i;
			prime[++m] = i;
			phi[i] = i - 1;
		}
		for(int j = 1; j <= m; ++j) {
			if(prime[j] > v[i] || prime[j] > n / i)	break;
			v[i * prime[j]] = prime[j];
			phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);
		}
	}
}
  • BSGS
inline int BSGS(int a, int b, int p = mod) {
	map<int, int> Hash;
	Hash.clear();
	b %= p;
	int t = (ll)sqrt(p) + 1;
	for(int j = 0; j < t; ++j) {
		int val = (ll)b * quickpow(a, j) % p;
		Hash[val] = j;
	}
	a = quickpow(a, t);
	if(!a)	return !b ? 1 : -1;
	for(int i = 0; i < t; ++i) {
		int val = quickpow(a, i);
		int j = Hash.find(val) == Hash.end() ? -1 : Hash[val];
		if(j >= 0 && i * t - j >= 0)	return i * t - j;
	}
	return -1;
}

完整代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int mod = 998244353, N = 1e7, M = 3000;

inline ll read() {
	ll s = 0, f = 1;
	char ch;
	for(; ch < '0' || ch > '9'; ch = getchar())	if(ch == '0')	f = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar())	s = (s << 1) + (s << 3) + ch - '0';
	return s * f;
}

inline ll add(ll a, ll b) { return (a += b) >= mod ? a - mod : a; }
inline ll sub(ll a, ll b) { return (a -= b) < 0 ? a + mod : a; }
inline ll mul(ll a, ll b) { return a * b % mod; }

inline void Add(ll &a, ll b) { a = add(a, b); }
inline void Sub(ll &a, ll b) { a = sub(a, b); }
inline void Mul(ll &a, ll b) { a = mul(a, b); }

inline ll quickpow(ll a, ll b) {
	ll re = 1;
	while(b) {
		if(b & 1)	Mul(re, a);
		b >>= 1;
		Mul(a, a);
	}
	return re;
}

inline ll get_inv(ll x) { return quickpow(x, mod - 2); }

inline ll greatmul(ll a, ll b) { return add(sub(a * b, (ll)(((long double)a * b + 0.5) / mod) * mod), mod); }
inline void GreatMul(ll &a, ll b) { a = greatmul(a, b); }

inline ll Quickpow(ll a, ll b) {
	ll re = 1;
	while(b) {
		if(b & 1)	GreatMul(re, a);
		b >>= 1;
		GreatMul(a, a);
	}
	return re;
}

inline ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
inline ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

inline ll exgcd(ll a, ll b, ll &x, ll &y) {
	if(!b) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = exgcd(b, a % b, x, y);
	ll z = x;
	x = y;
	y = z - (a / b) * y;
	return d;
}

ll fac[N + 10], inv[N + 10], c[M + 10][M + 10];
inline void input() {
	fac[0] = 1;
	for(int i = 1; i <= N; ++i)	fac[i] = mul(fac[i - 1], i);
	inv[N] = get_inv(fac[N]);
	for(int i = N; i >= 1; --i)	inv[i - 1] = mul(inv[i], i);
	c[0][0] = 1;
	for(int i = 1; i <= M; ++i) {
		c[i][0] = 1;
		for(int j = 1; j <= i; ++j)
			c[i][j] = add(c[i - 1][j], c[i - 1][j - 1]);
	}
}

inline ll C(ll n, ll m) {
	if(n < m || n < 0 || m < 0)	return 0;
	return mul(fac[n], mul(inv[m], inv[n - m]));
}

int v[N + 10], prime[(N + 10) / 10], phi[N], m;
inline void euler(int n) {
	memset(v, 0, sizeof(v));
	m = 0;
	for(int i = 2; i <= n; ++i) {
		if(!v[i]) {
			v[i] = i;
			prime[++m] = i;
			phi[i] = i - 1;
		}
		for(int j = 1; j <= m; ++j) {
			if(prime[j] > v[i] || prime[j] > n / i)	break;
			v[i * prime[j]] = prime[j];
			phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);
		}
	}
}

inline int BSGS(int a, int b, int p = mod) {
	map<int, int> Hash;
	Hash.clear();
	b %= p;
	int t = (ll)sqrt(p) + 1;
	for(int j = 0; j < t; ++j) {
		int val = (ll)b * quickpow(a, j) % p;
		Hash[val] = j;
	}
	a = quickpow(a, t);
	if(!a)	return !b ? 1 : -1;
	for(int i = 0; i < t; ++i) {
		int val = quickpow(a, i);
		int j = Hash.find(val) == Hash.end() ? -1 : Hash[val];
		if(j >= 0 && i * t - j >= 0)	return i * t - j;
	}
	return -1;
}

int main() {
	
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值