快速幂,最大公约数(gcd)

快速幂
没什么好说的,直接上代码

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);  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值