乘法的范围乘法、范围

2023-09-11 06:34:52 作者:浅浅の夏づ

我有一个数组10个号码supprse A [10] = {1,2,3,4,5,6,7,8,9,10} 我必须计算数字在特定范围内的乘法,但没有得到正确的答案,我使用的段树和不知道如何使用查询操作 这是我的code:

 #包括< stdio.h中>
#定义米10亿
#定义MAX 100010

的typedef无符号长长ULL;
ULL一个[MAX]
ULL树[4 * MAX]。

无效build_tree(INT N,INT B,INT E){
    如果(B> E)的回报;
    否则,如果(二== E){
        树[N] = A [B];
        返回 ;
    }
    build_tree(N * 2面,b,(B + E)/ 2);
    build_tree(N * 2 + 1,(B + E)/ 2 + 1,E);
    树[N] =(树[N * 2]%M *树[N * 2 + 1]%M)%米;
}


ULL查询(INT指数,诠释SS,诠释本质,诠释QS,INT QE)
  {
      ULL P1,P2,磷;
      如果(QS> SE || QE< SS)
          返回-1;

      如果(SS> = QS及功放;&安培; SE< = QE)
          返回树[索引]
      P1 =查询(2 *指数,β,(β+ SE)/ 2,适量,QE);
      P2 =查询(2 *指数+1,(β+ SE)/ 2 + 1,本身,适量,QE);
      的printf(\ NP1 =%d个P2 =%d个,P1,P2);
      P =(树[P1]%M *树[P2]%M)%米;
      返回磷;

}
诠释的main(){
    INT N,I,query_start,query_end,segment_start,segment_end,指数;
    ULL值;
    scanf函数(%d个,和放大器; N);
    对于(I = 0; I&n种;我+ +)
       scanf函数(%LLD,和放大器; A [1]);
    build_tree(1,0,N-1);
    query_start = 1;
    query_end = 2;
    segment_start = 0;
    segment_end = N-1;
    索引= 1;
    的printf(树形成的: -  \ N);
    对于(I = 0; I&n种* 4;我+ +)
          的printf(%D,树[I]);
    的printf(\ñ\ N);
    值=查询(索引,segment_start,segment_end,query_start,query_end);
    的printf(\ n值=%LLD \ N,值);
    返回0;
}
 

解决方案

这是稍微偏离主题,但主要是张贴这是萨沙萨米人的响应。这仍然可以作为一个替代的想法来解决的任择议定书的问题。

八年级数学上册 分解因式 50例

如果没有问题,我们并不真正需要使用线段树。这样做是为了让另一个数组包含值的累计产品输入数组中

因此​​,如果输入数组是

  [1,2,3,4,5,6,7,8,9,10]
 

相应的产品阵列将是:

  [1,2,6,24,120,720,5040,40320,362880,3628800]
 

现在,我们知道所有元素的产物[0,1]任何索引i。要获得指数i和j之间的产品,我们就可以得到产品[0,J]和[0,1],并用它来得到我们的答复。该产品为[I,J]居然是[0,D] / [0,I - 1]。为了避免专门办案其中i = 0,我们也可以把它改写为[0,D] / [0,1] *在我的元素。

code(在Python):

 #!在/ usr /斌/蟒蛇


高清build_products_array(阵列):
RET = [0,我的xrange(LEN(阵列))]
RET [0] =阵列[0]
LAST_VALUE = 1,如果数组[0]其他数组[0]
对我的xrange(1,LEN(阵列)):
如果数组[我]:
RET [我] = LAST_VALUE *数组[我]
LAST_VALUE = RET [I]
    其他:
RET [我] = LAST_VALUE
返回RET


高清build_zero_array(阵列):
RET = [0,我的xrange(LEN(阵列))]
RET [0] = 0,如果数组[我]其他1
对我的xrange(1,LEN(阵列)):
RET [i] = RET [我 -  1] +(0,如果数组[我]其他1)
返回RET


高清check_zeros(zero_array,数组,I,J):
返回zero_array [J]  -  zero_array [I] +(0,如果数组[我]其他1)


高清查询(产品,zero_array,数组,开始,结束):
如果check_zeros(zero_array,数组,开始,结束):
返回0
  其他:
回报的产品[结束] /产品[开始] *阵列[开始]


高清的main():
阵列= [1,2,3,4,5,0,7,8,9,10]
产品= build_products_array(阵列)
零= build_zero_array(阵列)
对我的xrange(LEN(阵列)):
对于j中的xrange(我,LEN(阵列)):
打印查询[%D,%D]:%D \ N%(I,J,查询(产品,零,数组,I,J))


如果__name__ =='__main__':
  主要()
 

的事情需要注意的是溢出,因为累积的产品可以得到相当大的,即使答案的查询,保证足够小。 C时上述$ C $在Python,所以没有担心溢出的存在,但在C ++中,你可能需要使用大数。它,如果你需要找到产品还易于使用的模一定数量的 - 在这种情况下,溢出不是一个问题。

这方法也将查找范围内的数字,或为其逆操作也存在任何操作的总和(例如总和逆的是减法,对产品的倒数为师)。它不会像最大或最小操作的工作。

这需要O(n)的建立最初的产品阵列,每个查询是O(1)。因此,这实际上是比段树要快(为O其中查询(log n)的)。

编辑: 更新了code来处理零输入。我们一直在另一个阵列保持0的总数在每个索引处。对于每个查询,我们检查该数组,以查看是否有在该范围内的任何零(作为前,知道的计数为[0,i]和[0,j]中,我们可以计算出为计数[I,J]) )。如果有,这个问题的答案查询必须是0,否则我们返回产品。

I have an array to 10 numbers supprse A[10] = {1,2,3,4,5,6,7,8,9,10} and I have to compute the multiplication of numbers in a particular range but not getting correct answer, I am using segment tree and dont know how to use query operation Here is my code :

#include<stdio.h>
#define m 1000000000
#define MAX 100010

typedef unsigned long long ull;
ull a[MAX];
ull tree[4*MAX];

void build_tree(int n,int b,int e){
    if(b>e)return ;
    else if(b==e){
        tree[n] = a[b];
        return ;
    }
    build_tree(n*2,b,(b+e)/2);
    build_tree(n*2+1,(b+e)/2+1,e);
    tree[n] =( tree[n*2]%m * tree[n*2 + 1]%m )%m;
}


ull query(int index, int ss, int se, int qs, int qe)
  {
      ull p1, p2,p;
      if (qs > se || qe < ss)
          return -1;

      if (ss >= qs && se <= qe)
          return tree[index];
      p1 = query(2 * index, ss, (ss + se) / 2, qs, qe);
      p2 = query(2 * index + 1, (ss + se) / 2 + 1, se,qs, qe);
      printf("\np1 = %d   p2 = %d",p1,p2);
      p=(tree[p1]%m*tree[p2]%m)%m;
      return p;

}
int main(){
    int n,i,query_start,query_end,segment_start,segment_end,index;
    ull value;
    scanf("%d",&n);
    for(i=0;i<n;i++)
       scanf("%lld",&a[i]);
    build_tree(1,0,n-1);
    query_start=1;
    query_end=2;
    segment_start=0;
    segment_end = n-1;
    index=1;
    printf("Tree Formed :-\n");
    for(i=0;i<n*4;i++)
          printf("%d  ",tree[i]);
    printf("\n\n");
    value=query(index,segment_start,segment_end,query_start,query_end);
    printf("\nvalue = %lld\n",value);
    return 0;
}

解决方案

This is slightly off topic, but posting this mainly as a response to sasha sami. This still works as an alternate idea to solve the OP's problem.

If there are no queries, we don't really need to use a segment tree. The idea is to keep another array containing the cumulative products of the values in the input array.

So, if the input array is

[1,2,3,4,5,6,7,8,9,10]

The corresponding product array will be:

[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

Now, we know the product of all elements [0, i] for any index i. To get the product between indices i and j, we can just get the product for [0, j] and [0, i] and use that to get our answer. The product for [i, j] is actually [0, j] / [0, i - 1]. To avoid specially handling the case where i = 0 we can also rewrite it as [0, j] / [0, i] * element at i.

Code (in Python):

#! /usr/bin/python


def build_products_array(array):
  ret = [0 for i in xrange(len(array))]
  ret[0] = array[0]
  last_value = 1 if array[0] else array[0]
  for i in xrange(1, len(array)):
    if array[i]:
      ret[i] = last_value * array[i]
      last_value = ret[i]
    else:
      ret[i] = last_value
  return ret


def build_zero_array(array):
  ret = [0 for i in xrange(len(array))]
  ret[0] = 0 if array[i] else 1
  for i in xrange(1, len(array)):
    ret[i] = ret[i - 1] + (0 if array[i] else 1)
  return ret


def check_zeros(zero_array, array, i, j):
  return zero_array[j] - zero_array[i] + (0 if array[i] else 1)


def query(products, zero_array, array, start, end):
  if check_zeros(zero_array, array, start, end):
    return 0
  else:
    return products[end] / products[start] * array[start]


def main():
  array = [1, 2, 3, 4, 5, 0, 7, 8, 9, 10]
  products = build_products_array(array)
  zeros = build_zero_array(array)
  for i in xrange(len(array)):
    for j in xrange(i, len(array)):
      print "Querying [%d, %d]: %d\n" % (i, j, query(products, zeros, array, i, j))


if __name__ == '__main__':
  main()

The thing to watch out for is overflows because the cumulative products can get quite big, even if the answers to the queries are guaranteed to be small enough. The above code it in Python, so there's not fear of overflows there, but in C++ you might want to use bignums. Its also handy if you need to find the products modulo some number - in which case overflow is not an issue.

This approach will also work for finding the sum of a range of numbers, or any operation for which an inverse operation also exists (e.g. for sum the inverse is subtraction, for products the inverse is division). It wouldn't work for operations like max or min.

This takes O(n) to build the initial product array, and each query is O(1). So this is actually faster than segment tree (which queries in O(log n) ).

EDIT: Updated the code to handle zeros in the input. We keep another array keeping the total count of 0s at each index. For each query we check that array to see if there are any zeros in that range (as before, knowing the count for [0, i] and [0, j], we can figure out the count for [i, j])). If there are, the answer to that query must be 0. Otherwise we return the product.