- 快速幂与乘法运算
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;
}
本文深入探讨了快速幂运算及乘法优化技巧,包括快速幂实现、大数乘法处理,以及组合数学中常见的计算问题,如阶乘、逆元求解、组合数计算等。同时,文章提供了丢番图方程解法、最大公约数和最小公倍数的计算,以及线性筛法等高级算法。此外,还介绍了BSGS算法在离散对数问题中的应用。
2070

被折叠的 条评论
为什么被折叠?



