复数快速幂

来源:
在牛客寒假算法基础集训营的 F F F题中,有一种通法求解 ∑ n i ( i % 4 = = 0 ) × C n i \sum_n^i (i\%4==0)\times C_n^i ni(i%4==0)×Cni
但是需要求解 ( 1 + i ) n (1+i)^n (1+i)n ( 1 − i ) n (1-i)^n (1i)n
因此需要为复数重新实现一个复数快速幂。

前置:
复习一下复数乘法:
对于 ( 1 + i ) × ( 1 + i ) (1+i)\times (1+i) (1+i)×(1+i)
类似整数一样可以先乘出来再单独处理:
( 1 + i ) × ( 1 + i ) = i 2 + 2 i + 1 (1+i)\times (1+i)=i^2+2i+1 (1+i)×(1+i)=i2+2i+1
考虑复数有 i 2 = − 1 i^2=-1 i2=1
所以原式 = − 1 + 2 i + 1 = 2 i =-1+2i+1=2i =1+2i+1=2i

正文:
考虑在复数相乘时,存在实部和虚部两部分,所以定义两个变量分别表示实部和虚部即可。

复数定义:

struct Complex {
	ll a, b; // a + bi
	Complex(ll _a, ll _b) {
		a = _a, b = _b;
	}
};

实现相乘:

Complex mul(Complex A, Complex B) {
	ll a = ((A.a * B.a - A.b + B.b) % mod + mod) % mod;
	ll b = ((A.a * B.b + A.b * B.a) % mod + mod) % mod;
	return Complex(a, b); 
}

实现复数快速幂:

Complex C_qp(Complex A, ll b) {
	Complex ans(1, 0); //单位复数,即任意复数C乘单位复数都等于C
	while(b) {
		if(b & 1) ans = mul(ans, A);
		A = mul(A, A);
		b >>= 1;
	}
	return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值