2961.双模幂运算
给你一个下标从 0 开始的二维数组 variables ,其中 variables[i] = [ai, bi, ci, mi],以及一个整数 target 。
如果满足以下公式,则下标 i 是 好下标:
- 0 <= i < variables.length
- ((aibi % 10)ci) % mi == target
- 返回一个由 好下标 组成的数组,顺序不限 。
示例 :
输入:variables = [[2,3,3,10],[3,3,3,1],[6,1,1,4]], target = 2
输出:[0,2]
解释:对于 variables 数组中的每个下标 i :
- 对于下标 0 ,variables[0] = [2,3,3,10] ,(23 % 10)3 % 10 = 2 。
- 对于下标 1 ,variables[1] = [3,3,3,1] ,(33 % 10)3 % 1 = 0 。
- 对于下标 2 ,variables[2] = [6,1,1,4] ,(61 % 10)1 % 4 = 2 。
因此,返回 [0,2] 作为答案。
思路:这道题直接暴力模拟应该也可以过,数据量不大,但是让人更能反应起来的就是快速幂了…
下面简单回顾一下快速幂的算法思想
快速幂算法详解
快速幂算法用于高效地计算一个数(底数)( x ) 的 ( N ) 次方(即 ( x^N ))。该算法通过将指数 ( N ) 转换为二进制形式并使用平方的方法,来减少乘法操作的次数,从而大大提高计算效率。其时间复杂度为 ( O(\log N) )。
算法步骤
-
二进制表示:
- 将指数 ( N ) 转换为二进制。这是因为我们可以利用二进制的性质,只计算必要的乘法。
- 例如,( N = 13 ) 的二进制表示为 ( 1101 )。
-
分解指数:
- 根据二进制,( N ) 可以表示为:
[
N = 2^3 + 2^2 + 2^0 \quad \text{(即:} 13 = 8 + 4 + 1)
] - 因此,( x^{13} = x^8 \times x^4 \times x^1 )。
- 根据二进制,( N ) 可以表示为:
-
使用平方:
- 通过平方来逐步计算,具体如下:
- ( x^1 = x )
- ( x^2 = x \times x )
- ( x^4 = (x2)2 )
- ( x^8 = (x4)2 )
- 这允许我们通过平方减少实际的乘法次数。
- 通过平方来逐步计算,具体如下:
-
算法实现:
- 使用一个循环,逐位处理二进制表达的指数:
- 如果当前二进制位是 1,将对应的底数乘到结果中。
- 每次迭代都将底数平方,并进行指数的右移。
- 使用一个循环,逐位处理二进制表达的指数:
代码实现
下面是 Java 中的快速幂算法实现:
class Solution {
public double myPow(double x, int N) {
double ans = 1; // 初始化结果
long n = N; // 使用 long 来处理负数和溢出
if (n < 0) { // 当 N 为负时,取倒数
n = -n;
x = 1 / x;
}
while (n != 0) { // 处理每一个二进制位
if ((n & 1) == 1) { // 当前最低位是 1
ans *= x; // 将当前底数乘到结果中
}
x *= x; // 底数平方,为下一次的比特位做准备
n >>= 1; // 右移一位,处理下一个比特位
}
return ans; // 返回结果
}
}
## 示例演示
假设我们要计算 \( x = 2 \) 和 \( N = 13 \):
1. **二进制表示**:\( 13 \) 的二进制表示为 \( 1101 \)。
2. **计算步骤**:
- 从最低位开始:
- 第 0 位是 1,结果为 \( 2 \)(乘以底数 \( x \))。
- 单位平方:\( x = 2^2 = 4 \)
- 第 1 位是 0,结果不变。
- 单位平方:\( x = (2^2)^2 = 16 \)
- 第 2 位是 1,结果为 \( 2 \times 16 = 32 \)
- 单位平方:\( x = (4^2)^2 = 256 \)
- 第 3 位是 1,结果为 \( 32 \times 256 = 8192 \)
3. **最终结果**:
- \( 2^{13} = 8192 \)
## 总结
快速幂算法通过利用指数的二进制表示,结合平方和逐位乘法的方法,高效地计算出任意实数的指数次幂。它在各类计算中非常重要,特别在需要高效处理大数时表现尤为突出。
那么,对于本题,我们只要在快速幂的基础上,实现对应运算即可
AC代码
class Solution {
public List<Integer> getGoodIndices(int[][] variables, int target) {
List<Integer> ans = new ArrayList<Integer>();
for(int i=0;i<variables.length;i++)
{
int[] t = variables[i];
if(mypow(mypow(t[0],t[1],10),t[2],t[3])==target)
{
ans.add(i);
}
}
return ans;
}
private int mypow(int x,int n,int mod)
{
int ans = 1;
while(n!=0)
{
if((n&1)==1)
{
ans = ans * x %mod;
}
x = x*x%mod;
n>>=1;
}
return ans;
}
}