exgcd
//给定 a 和 b,求出 x 和 y,使得 a * x + b * y = gcd(a, b)
LL exgcd(LL a, LL b, LL &x, LL &y){
if (!b){
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= ( a / b ) * x;
return d;
}
gcd
LL gcd(LL a, LL b){
return b ? gcd(b, a % b) : a;
}
逆元
//1.快速幂求逆元
LL inv(LL x){
return qp(x, mod - 2, mod);
}
//2.扩展欧几里得求逆元
LL inv(LL a){
LL x, y;
exgcd(a, mod, x, y);
x = (x % mod + mod) % mod;
return x;
}
//3.线性递推求逆元
inv[1] = 1;
for (int i = 2; i <= n; i ++ )
inv[i] = (p - p / i) * inv[p % i] % p;
快输
void print(LL x){
if(x < 0) {putchar('-');x = -x;}
if(x / 10) print(x / 10);
putchar(x % 10 + '0');
}
lucas
LL qp(LL a, LL k, LL p){
LL ans = 1;
while (k){
if (k & 1) ans = ans * a % p;
k >>= 1;
a = a * a % p;
}
return ans;
}
LL C(LL a, LL b, LL p){
if (a < b) return 0;
LL x = 1, y = 1;
for (LL i = a, j = 1; j <= b; i --, j ++ ){
x = x * i % p;
y = y * j % p;
}
return x * qp(y, p - 2, p) % p;
}
LL lucas(LL a, LL b, LL p){
if (a < p && b < p) return C(a, b, p);
return C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}
sqrt
LL mySqrt(LL x){
LL k = sqrt(x) - 1;
while ((k + 1) * (k + 1) <= x) k++;
return k;
}
快速幂
LL qp(LL a, LL k, LL p){
LL ans = 1;
while (k){
if (k & 1) ans = ans * a % p;
k >>= 1;
a = a * a % p;
}
return ans;
}
快读
LL read(){
LL s = 0, w = 1;
char ch = getchar();
while ( ch < '0' || ch > '9') { if (ch == '-') w = -1; ch = getchar();}
while ( ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
unique
vector <LL> :: iterator unique(vector <LL> &a){
LL j = 0;
for (LL i = 0; i < a.size(); i++)
if (!i || a[i] != a[i - 1])
a[j++] = a[i];
return a.begin() + j;
}
自动取模整数型
template<int mod>
struct ModZ{
LL x;
constexpr ModZ() : x() {}
constexpr ModZ(LL x) : x(norm(x % mod)) {}
constexpr LL norm(LL x) {return (x % mod + mod) % mod;}
constexpr ModZ power(ModZ a, LL b) {ModZ res = 1; for (; b; b /= 2, a *= a) if (b & 1) res *= a; return res;}
constexpr ModZ inv() {return power(*this, mod - 2);}
constexpr ModZ &operator *= (ModZ rhs) & {x = norm(x * rhs.x); return *this;}
constexpr ModZ &operator += (ModZ rhs) & {x = norm(x + rhs.x); return *this;}
constexpr ModZ &operator -= (ModZ rhs) & {x = norm(x - rhs.x); return *this;}
constexpr ModZ &operator /= (ModZ rhs) & {return *this *= rhs.inv();}
friend constexpr ModZ operator * (ModZ lhs, ModZ rhs) {ModZ res = lhs; res *= rhs; return res;}
friend constexpr ModZ operator + (ModZ lhs, ModZ rhs) {ModZ res = lhs; res += rhs; return res;}
friend constexpr ModZ operator - (ModZ lhs, ModZ rhs) {ModZ res = lhs; res -= rhs; return res;}
friend constexpr ModZ operator / (ModZ lhs, ModZ rhs) {ModZ res = lhs; res /= rhs; return res;}
friend constexpr istream &operator >> (istream &is, ModZ &a) {LL v; is >> v; a = ModZ(v); return is;}
friend constexpr ostream &operator << (ostream &os, const ModZ &a) {return os << a.x;}
friend constexpr bool operator == (ModZ lhs, ModZ rhs) {return lhs.x == rhs.x;}
friend constexpr bool operator != (ModZ lhs, ModZ rhs) {return lhs.x != rhs.x;}
};
const int mod = 998244353;
using Z = ModZ<mod>;