
这一题又是在区间查询,一般是要用前缀和的,我刚开始的思路也是在用前缀和来解决,但出现的问题是因为数据过大,而这一题求的是前缀乘积,那么必须%1000000007,可是当用前缀乘积来得到查询结果的时候,会出现除法,而无法在进行模运算后进行除法运算,需要用一个逆元除法,这超出了我学习算法的范围,故放弃这种方法。
c++
class Solution {
public:
long long sum[100005];
vector<int> productQueries(int n, vector<vector<int>>& queries) {
//构建成功powers数组
//那么
vector<int> powers;
for (int i = 0; n > 0; i++) {
if (n & 1) powers.push_back(1 << i);
n >>= 1;
}
vector<int> ans;
sum[0]=1;
for(int i=0;i<powers.size();i++)
{
sum[i+1]=(sum[i]%1000000007*powers[i]%1000000007)%1000000007;
}
for(int i=0;i<queries.size();i++)
{
int l=queries[i][0];
int r=queries[i][1];
ans.push_back((sum[r+1]/sum[l]));
}
return ans;
}
};
实际上因为n是小于10^9的,那么powers数组中的元素最多大概也就30个,因此我们可以直接选择暴力的写法。
而这一道题的另一个关键点,就是在于如何得到powers数组,也即如何让一个数n分解成包含 最少 数目的 2 的幂,且它们的和为 n 。
我们只需将这个数写成二进制的形式即可,比如 100101,只需把为1的二进制的次幂提取出来即可
而对一个数的二进制的处理,需要掌握好位运算,就能很好的解决。
c++
vector<int> powers;
for (int i = 0; n > 0; i++) {
if (n & 1) powers.push_back(1 << i);
n >>= 1;
}
得到powers数组后,暴力模拟即可
最终代码如下:
c++
class Solution {
public:
vector<int> productQueries(int n, vector<vector<int>>& queries) {
//构建成功powers数组
//那么
vector<int> powers;
for (int i = 0; n > 0; ++i) {
if (n & 1) powers.push_back(1 << i);
n >>= 1;
}
//因为n=10^9,所以power最多有30个元素
//那么我们可以直接用暴力写
vector<int> ans;
for(int i=0;i<queries.size();i++)
{
long long x=1;
int l=queries[i][0];
int r=queries[i][1];
for(int j=l;j<=r;j++)
{
x=(x%1000000007*powers[j]%1000000007)%1000000007;
}
ans.push_back(x);
}
return ans;
}
};
时间复杂度大概O(30^n)。