要动态在末尾加入一个数,查询最后k个数的乘积,k不定。
- 维护每个数往前乘积的倍增数组再求和。
- 直接维护前缀积,遇到零就重置为1,因为题目求的不是一般的区间和,而是最后k个数,所以直接置1是对的。
code1
class ProductOfNumbers {
public:
int n;
int ze;
int a[40050];
//f表示向前乘积的倍增数组
int f[40050][35];
ProductOfNumbers() {
n=0;
ze=-1;
}
void add(int num) {
a[++n]=num;
if(num==0){
ze=n;
}
f[n][0]=a[n];
for(int i=1;(1<<i)<=n;i++){
f[n][i]=f[n][i-1]*f[n-(1<<(i-1))][i-1];
}
}
int getProduct(int k) {
if(ze>n-k){
return 0;
}
int ans=1;
int j=n;
for(int i=15;i>=0;i--){
if(k&(1<<i)){
ans*=f[j][i];
j-=(1<<i);
}
}
return ans;
}
};
/**
* Your ProductOfNumbers object will be instantiated and called as such:
* ProductOfNumbers* obj = new ProductOfNumbers();
* obj->add(num);
* int param_2 = obj->getProduct(k);
*/
code2
class ProductOfNumbers {
public:
int n;
int ze;
int a[40050];
ProductOfNumbers() {
n=0;
ze=-1;
a[0]=1;
}
void add(int num) {
n++;
if(num){
a[n]=a[n-1]*num;
}else{
ze=n;
a[n]=1;
}
}
int getProduct(int k) {
if(ze>n-k){
return 0;
}
return a[n]/a[n-k];
}
};
/**
* Your ProductOfNumbers object will be instantiated and called as such:
* ProductOfNumbers* obj = new ProductOfNumbers();
* obj->add(num);
* int param_2 = obj->getProduct(k);
*/