C++ 不能';我不知道我的二叉索引树解决方案有什么问题

C++ 不能';我不知道我的二叉索引树解决方案有什么问题,c++,algorithm,binary-indexed-tree,C++,Algorithm,Binary Indexed Tree,我正在解决一个问题 Count of Range Sum Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j),inclusi

我正在解决一个问题

    Count of Range Sum

    Given an integer array nums, return the number of range sums that 
    lie in [lower, upper] inclusive. Range sum S(i, j) is defined as 
    the sum of the elements in nums between indices i and j (i ≤ j),inclusive.
    Example: Given nums = [-2, 5, -1], lower = -2, upper = 2, Return 3.
    The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2
我的解决方案如下:

1.将[0,i]中的所有和作为和[i]

2.将总和向量排序为克隆向量,并根据其在克隆向量中的索引重新索引总和中的元素。将总和元素值作为映射反映的键,新索引作为反映的值。将向量和元素从后向前添加到二叉索引树中,同时在克隆中找到满足上下限条件的有效元素索引范围[idx1,idx2]

3.在我们的位中获取从节点0到节点idx1的和以及从节点0到节点idx2的和。如果节点已经插入位中,我们将在位中找到节点。所以满足我们的约束条件的节点数量是和

 public:
 vector<long>tree,clone;
 int countRangeSum(vector<int>& nums, int lower, int upper) {
 int n=nums.size();
 vector<long>sum(n+1);
 for(int i=1;i<=n;i++)
 sum[i]=sum[i-1]+nums[i-1];// step1

 clone=sum;
 sort(clone.begin(),clone.end());
 tree.resize(sum.size()+1);
 unordered_map<long,int>reflect;
 for(int i=0;i<clone.size();i++)
 reflect[clone[i]]=i;//step2

 int res=0;
 for(int i=sum.size()-1;i>=0;i--)
 {

   int idx1=binarysearch(sum[i]+lower,true);
   int idx2=binarysearch(sum[i]+upper,false);

   res=res+count(idx2)-count(idx1);
   add(reflect[sum[i]]); //step3
 }
 return res;
 }




 int binarysearch(long val, bool includeself)
{  
if(includeself)
return lower_bound(clone.begin(),clone.end(),val)-clone.begin();
return upper_bound(clone.begin(),clone.end(),val)-clone.begin();
}





void add(int pos){
pos=pos+1;
while(pos<tree.size())
{
    tree[pos]++;
    pos=pos+(pos&-pos);
}
}




int count(int pos){
int cnt=0;
pos=pos+1;
while(pos>0)
{
    cnt=cnt+tree[pos];
    pos=pos-(pos&-pos);
}
return cnt;
}
公共:
矢量树,克隆;
int countRangeSum(向量和nums、整数下限、整数上限){
int n=nums.size();
向量和(n+1);

对于(inti=1;i我很难理解您是如何尝试使用二叉索引树的,但我想我明白了

让我试着解释一下我认为的算法是什么,使用n作为输入数组的长度

  • 计算范围以索引0开始的所有范围和
  • 按递增顺序对这些总和进行排序
  • 初始化大小为n的二元索引树,该树表示每个位置的频率计数为0。这表示您开始使用的所有和都无效,并将用于跟踪随着算法的进行哪些和变为有效
  • 隐式地用范围和S(0,n)偏移所有和,以便获得范围以索引n而不是索引0开始的范围和
  • 确定[下限,上限]中最小和最大和的排序和列表中的索引
  • 查询二元索引树以计算这些和中有多少是有效的。将其添加到属于[下限,上限]的范围和总数中
  • 在二元索引树中标识范围和S(0,n)的索引,并通过将其频率计数设置为1,在下一次迭代中将其标记为有效和
  • 循环回到步骤4,遍历n-1、n-2、n-3、…、2、1、0
  • 我认为,您的实现中最重要的问题是您的树不够大。它应该稍微大一点,因为没有使用0索引。所以请使用

    tree.resize(sum.size()+2);
    
    而不是您当前的
    +1

    此外,如果您希望能够多次使用该方法,则需要清除树,将所有值设置回零,而不仅仅是调整其大小


    修复了第一个问题后,它可以在示例数据上运行。我没有注意到您的代码有任何其他问题,但我没有进行彻底的测试。

    请帮助我们帮助您。代码出了什么问题?您是否遇到编译器错误?运行时错误?错误的结果?在任何情况下,您都应该发布一个错误,并请在代码正确的时候正确格式化代码很难阅读我强烈推荐一种工具,也许你听说过,叫做调试器。它对于查找代码中的问题非常有用。