1.幂运算
幂运算是数学中的一个基本运算,用于表示一个数的指数次幂。它将一个数(称为底数)乘以自身多次,次数由另一个数(称为指数)指定。
幂运算的一般形式为:
其中,a
是底数,n
是指数。底数表示要进行幂运算的数,指数表示底数要乘以自身的次数。
幂运算的结果为底数的指数次幂。例如,2的3次幂可以表示为2^3,计算结果为8。这意味着2乘以自身3次,即2 * 2 * 2 = 8。
幂运算具有以下性质:
- 任何数的0次幂等于1,即。
- 任何数的1次幂等于其本身,即。
- 幂运算满足指数相加的规则,即
- 幂运算满足指数相乘的规则,即。
幂运算在数学和计算机科学中广泛应用,例如在代数、几何、物理学、计算机图形学等领域中。在编程中,幂运算可以帮助我们进行数字的快速计算和指数增长的模拟。
2.快速幂
对于幂运算,如果一个一个乘,计算量为O(n)。如果用到快速幂计算,只需要计算O()次。
快速幂(Fast Power)是一种优化的算法,用于高效地计算幂运算。它通过利用指数的二进制表示形式来减少乘法运算的次数,从而提高计算效率。
快速幂算法的基本思想是将指数逐渐减半,并利用底数的平方递归计算。
以计算为例说明如下
(1)幂次与二进制的关系。把分解为,其中,,,...的幂次都是2的倍数,所有幂都是倍乘关系,可以逐级递推
(2)幂次用二进制分解。如何把11分解为8+2+1?利用数学的二进制特征,,只需要把n按二进制处理就可以了。
(3)如何跳过那些没有的幂次?例如需要跳过。做一个判断即可,用二进制位运算实现,即
n&1,取n的最后一位,并且判断这一位是否需要跳过。
n>>=1,把n右移一位,目的是把刚处理过的n的最后一位去掉。
-
&
运算符(按位与):&
运算符执行按位与操作,对两个操作数的每一位执行逻辑与操作,并返回一个新的整数,其中每一位都是两个操作数对应位的逻辑与结果。- 例如,假设有两个整数
a = 5
(二进制表示为0101
)和b = 3
(二进制表示为0011
),则a & b
的结果为1
(二进制表示为0001
)。
-
>>
运算符(右移):>>
运算符将二进制表示的数向右移动指定的位数。- 对于有符号整数,右移操作将保留符号位并将其他位向右移动。例如,对于有符号整数
-7
(二进制表示为11111111111111111111111111111001
),执行-7 >> 2
将得到-2
(二进制表示为11111111111111111111111111111110
)。 - 对于无符号整数,右移操作将在左侧插入零位。例如,对于无符号整数
7
(二进制表示为00000000000000000000000000000111
),执行7 >> 2
将得到1
(二进制表示为00000000000000000000000000000001
)。
-
<<
运算符(左移):<<
运算符将二进制表示的数向左移动指定的位数。- 左移操作将在右侧插入零位。例如,对于整数
5
(二进制表示为00000000000000000000000000000101
),执行5 << 2
将得到20
(二进制表示为00000000000000000000000000010100
)。
int fastpow(int a, int n) {
int ans = 1;//用ans作为返回值
while (n) {//把n看作二进制数,逐个处理最后一位
if (n & 1)ans *= a;//如果n的最后一位为1,表示这个地方需要乘
a *= a;//递推a^1,a^2,a^4....
n >>= 1;//把n右移一位
}
return ans;
}
幂运算往往是大数,一般先取模在输出。根据取模的性质
上述代码即为
ll fastpow(ll a, ll n, ll mod) {
ll ans = 1;//用ans作为返回值
a %= mod;//在一定程度上防止a*a越界
while (n) {//把n看作二进制数,逐个处理最后一位
if (n & 1)ans = (ans * a) % mod;//如果n的最后一位为1,表示这个地方需要乘
a = (a * a) % mod;//递推a^1,a^2,a^4....
n >>= 1;//把n右移一位
}
return ans;
}