题目描述
给你一个整数数组 nums
,一个整数 k
和一个整数 multiplier
。
你需要对 nums
执行 k
次操作,每次操作中:
- 找到
nums
中的 最小 值x
,如果存在多个最小值,选择最 前面 的一个。 - 将
x
替换为x * multiplier
。
k
次操作以后,你需要将 nums
中每一个数值对 109 + 7
取余。
请你返回执行完 k
次乘运算以及取余运算之后,最终的 nums
数组。
示例 1:
输入:nums = [2,1,3,5,6], k = 5, multiplier = 2
输出:[8,4,6,5,6]
解释:
操作 | 结果 |
---|---|
1 次操作后 | [2, 2, 3, 5, 6] |
2 次操作后 | [4, 2, 3, 5, 6] |
3 次操作后 | [4, 4, 3, 5, 6] |
4 次操作后 | [4, 4, 6, 5, 6] |
5 次操作后 | [8, 4, 6, 5, 6] |
取余操作后 | [8, 4, 6, 5, 6] |
示例 2:
输入:nums = [100000,2000], k = 2, multiplier = 1000000
输出:[999999307,999999993]
解释:
操作 | 结果 |
---|---|
1 次操作后 | [100000, 2000000000] |
2 次操作后 | [100000000000, 2000000000] |
取余操作后 | [999999307, 999999993] |
提示:
1 <= nums.length <= 104
1 <= nums[i] <= 109
1 <= k <= 109
1 <= multiplier <= 106
AC代码
class Solution {
public:
const int MOD = 1e9 + 7;
//快速幂
inline long long fpow(long long x, long long y) {
long long re = 1;
for (; y; y >>= 1) {
if (y & 1) re = (x * re) % MOD;
x = (x * x) % MOD;
}
return re;
};
vector<int> getFinalState(vector<int>& nums, int K, int multiplier) {
if (multiplier == 1) return nums;
int n = nums.size();
int m = 0;
for (int i = 1; i < n; i++) {
if (nums[i] >= nums[m]) m = i;
}
priority_queue <pair<long long int, int>, vector<pair<long long int, int>>, //
greater<pair<long long int, int>>> s; //构造小堆
vector<long long int> num;
vector<int> ans;
//最小堆模拟
for (int i = 0; i < n; i++) {
s.push({nums[i], i});
num.push_back(nums[i]);
}
while (K--) {
pair<long long, int> p = s.top(); //操作最小值
//处理堆
p.first *= multiplier;
s.pop();
s.push(p);
//处理向量
num[p.second] = (num[p.second] * multiplier) % MOD;
if (p.second == m) break;
}
//循环操作
for (int n1 = 0; n1 < n; n1++) {
int i = s.top().second;
int last = K / n + (n1 < (K % n) ? 1 : 0);
num[i] = (num[i] * fpow(multiplier, last)) % MOD;
s.pop();
}
for (long long int ele : num) { //long long int 转 int 输出结果
ans.push_back(ele);
}
return ans;
}
};