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