来源:
在牛客寒假算法基础集训营的 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 (1−i)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;
}