lnk-k

导航

 

复习数学知识
快速幂

long long qbow(long long a, long long b, long long p){
  long long res=1;
  while(b){
    if(b&1)res=res*a%p;
    a=a*a%p;
    b>>=1;
  }
  return res;
}

最大公约数(还是记一下吧)

int gcd(int a,int b){
  return b==0?a:gcd(b,a%b); 
}

扩展欧几里得算法(Extended Euclidean algorithm, EXGCD),常用于求
\(ax+by=gcd(a,b)\) 的一组可行解.

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

费马小定理:设 \(p\) 是素数。对于任意整数 \(a\)\(p \nmid a\),都有

\[a^{p-1} \equiv 1 \pmod{p} \]

\(p\)是素数.对于任意整数\(a\),都成立

\[a^{p}\equiv a\pmod p \]

欧拉定理:对于整数\(m>0\)和整数\(a\),且\(gcd(a,m)=1\)

\[a^{\varphi(m)}\equiv 1\pmod{m} \]

,其中,\(\varphi(n)\)为 欧拉函数.
求模逆元:利用扩展欧几里得算法或快速幂法,可以在\(O(\log m)\)时间内求出单个整数的逆元.
扩展欧几里得算法

// Extended Euclidean algorithm.
void exgcd(int a,int b,int& x,int& y){
  if(!b){
    x=1;
    y=0;
  }
  else{
    exgcd(b,a%b,y,x);
    y-=a/b*x;
  }
}

// Returns the modular inverse of a modulo m.
// Assumes that gcd(a, m) = 1, so the inverse exists.
int inverse(int a,int m){
  int x,y;
  exgcd(a,m,x,y);
  return(x%m+m)%m;
}

(但是一般都用快速幂吧,mod一般都是质数啥的)
快速幂:

// Binary exponentiation.
int qpow(int a, int b,int m){
  long long res=1;
  while(b){
    if(b&1)res=res*a%m;
    a=a*a%m;
    b>>=1;
  }
  return res;
}

// Returns the modular inverse of a prime modulo p.
int inverse(int a,int p){return qpow(a,p-2,p);}

线性同余方程:
设 𝑎,𝑏,𝑛
a,b,n 为整数,𝑥
x 为未知数,那么,形如

\[ax\equiv b\pmod n \]

的方程称为 线性同余方程(linear congruence equation).

// Extended Euclidean Algorithm.
// Finds integers x, y such that a*x + b*y = gcd(a, b),
// and returns gcd(a, b).
int exgcd(int a,int b,int& x,int& y){
  if(!b){
    x=1;
    y=0;
    return a;
  } 
  else{
    int d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
  }
}

// Solves the linear congruence equation:
//     a * x ≡ b (mod n), where n > 0.
// Returns the smallest non-negative solution x,
// or -1 if there is no solution.
int solve(int a,int b,int n){
  int x,y;
  int d=exgcd(a,n,x,y);
  if(b%d)return -1;
  n/=d;
  return ((long long)x*(b/d)%n+n)%n;
}

中国剩余定理:

LL CRT(int k, LL* a, LL* r) {
  LL n = 1, ans = 0;
  for (int i = 1; i <= k; i++) n = n * r[i];
  for (int i = 1; i <= k; i++) {
    LL m = n / r[i], b, y;
    exgcd(m, r[i], b, y);  // b * m mod r[i] = 1
    ans = (ans + a[i] * m * b % n) % n;
  }
  return (ans % n + n) % n;
}

阶乘以及阶乘逆元:

fac[0] = 1;
for (int i = 1; i <= k; i++) fac[i] = fac[i - 1] * i % MOD;
inv[k] = qpow(fac[k], MOD - 2);
for (int i = k - 1; i >= 0; i--) inv[i] = inv[i + 1] * (i + 1) % MOD;

找不到lucas算组合数的板子了。。。找不到算了

posted on 2026-03-13 20:14  1uoan  阅读(9)  评论(0)    收藏  举报