算法学习:快速幂,欧拉函数,BSGS,中国剩余,卢卡斯定理板子合集
【最大公约数】
1 ll qpow(ll a, ll x) 2 { 3 ll ret = 1; 4 while (x) 5 { 6 if (x & 1) 7 { 8 ret = (ret * a) % mod; 9 } 10 a = (a * a) % mod; 11 x >>= 1; 12 } 13 return ret; 14 }
【扩展欧几里得】
1 void exgcd(ll a, ll b) 2 { 3 if (!b) 4 { 5 x = 1, y = 0; 6 return; 7 } 8 exgcd(b, a % b); 9 ll tmp = x; 10 x = y; 11 y = tmp - (a / b) * y; 12 }
【快速幂】
1 ll qpow(ll a, ll x) 2 { 3 ll ret = 1; 4 while (x) 5 { 6 if (x & 1) 7 { 8 ret = (ret * a) % mod; 9 } 10 a = (a * a) % mod; 11 x >>= 1; 12 } 13 return ret; 14 }
【中国剩余】
1 ll excrt(ll n) 2 { 3 ll x, y, k; 4 ll M = bi[1], ans = ai[1]; 5 for (int i = 2; i <= n; i++) 6 { 7 ll a = M, b = bi[i], c = (ai[i] % b - ans % b + b) % b; 8 ll gcd = exgcd(a, b, x, y); 9 ll bg = b / gcd; 10 if (c % gcd != 0) 11 return -1; 12 x = qpow(x, c / gcd, bg); 13 ans += x * M; 14 M *= bg; 15 ans = (ans % M + M) % M; 16 } 17 return (ans % M + M + M) % M; 18 }
【BSGS】
1 ll BSGS(ll b, ll n) 2 { 3 if (b % mod == 0) { 4 5 return -1; 6 } 7 int m = (int)(sqrt(mod)); 8 mapp[n % mod] = 0; 9 for (int i = 1; i <= m;i++) 10 { 11 mapp[qpow(b, i) * n % mod] = i; 12 } 13 long long t = qpow(b, m), ans = 1; 14 for(int i=1;i<=m;i++) 15 { 16 ans = (ans * t) % mod; 17 if (mapp[ans]) 18 { 19 long long q = i * m - mapp[ans]; 20 return ((q % mod + mod) % mod); 21 } 22 } 23 return -1; 24 }