快速幂
没什么好说的,直接上代码
LL pow_mod(LL a, LL b){//a的b次方
if(b == 0) return 1;
LL ret = pow_mod(a, b/2);
ret = ret * ret % MOD;
if(b % 2 == 1) ret = ret * a % MOD;
return ret;
}
a的b次方=a的b/2次方*a的b/2次方;
依次递归下去
这里的幂是成倍增长的
乘法肯定比加法快
这里默认是要求模的情况
快速乘(一样)
LL mul(LL a, LL b, LL p){//快速乘,计算a*b%p
LL ret = 0;
while(b){
if(b & 1) ret = (ret + a) % p;
a = (a + a) % p;
b >>= 1;
}
return ret;
}
最大公约数(gcd)
辗转相除(欧几里得算法)
这个就用不着解释了吧
LL gcd(LL a, LL b){
if(b == 0) return a;
else return gcd(b, a%b);
}
LL gcd(LL a, LL b){
return b ? gcd(b, a%b) : a;
}
//两种都可以
lcm(最小公倍数) = a * b / gcd
(注意,这样写法有可能会错,因为a * b可能因为太大 超出int 或者 超出 longlong)
所以推荐写成 : lcm = a / gcd * b
下面的应该很好理解吧:
gcd(ka, kb) = k * gcd(a, b)
lcm(ka, kb) = k * lcm(a, b)
这里存一个求多项式最大公共项的模板:
vector<int> G[maxn];
int mod;
int pow_mod(int a, int b) {
int ans = 1;
while (b) {
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
/*多项式求最大公共项*/
vector<int> poly_gcd(vector<int> a,vector<int> b) {
if (b.size() == 0)
return a;
int t = a.size() - b.size();
vector<int> c;
for (int i = 0;i <= t; i++) {
int tmp = a[i] * pow_mod(b[0],mod-2)%mod;
for (ll j = 0; j < b.size(); j++)
a[i+j] = (a[i+j] - tmp * b[j]%mod + mod)%mod;
}
int p = -1;
for (int i = 0;i < a.size(); i++) {
if (a[i] != 0) {
p = i;
break;
}
}
if (p >= 0) {
for (int i = p; i < a.size(); i++)
c.push_back(a[i]);
}
return poly_gcd(b,c);
}