mat*_*hse 6 c++ algorithm tree stochastic-process
问题: 我偶然发现了Fenwick树(二元索引树),它们可以轻松计算累积总和.但是,我只发现了leeves(summands)数量不变的实现(但它们的值可以改变).有没有类似于广义Fenwick树的东西,允许改变leeves(summands)的数量,即具有可变大小?
背景 我正在编写一些随机模拟代码(用C++编写):在一个瓮中有球,每个球我有一定的概率p_i被绘制.在绘图事件中,球被绘制(并被移除)并被具有新概率的两个新球替换(并且相应地重新调整所有概率;我已经有效地"重新缩放",因此不要打扰它).在某些时候,我开始移除球,使得球的数量围绕恒定值(之前已知)波动.为了有效地进行绘图,我想使用二叉树.标准的Fenwick树完全符合我的要求,只是它不允许更改urn中的球数.
典型的数字 从10个球开始,添加球并且一旦有大约1000个就开始移除球,使得在球中有900到1100个球(即球被添加和移除使得数量保持在1000左右).
到目前为止的解决方法 估计所需的最大球数(具有一些安全范围,比如1200个球),并使大小的恒定大小的Fenwick树具有最大概率为0的大部分球被绘制并连续更新.
非常感谢您的帮助!马蒂亚斯
实际上,正常(不以任何方式概括)Fenwick树允许随时增加叶子的数量.
某些特定实现可能不允许它.但这可以修复.例如,从TopCoder实现不允许更改叶子数.问题是update
函数修改了从给定索引开始并向上运行的数组元素,当它达到某个limit(MaxVal
)时停止,在我们的例子中,这是预先不知道的.read
函数迭代向下的数组元素,因此它不需要知道当前的数组大小.如果我们在update
和之间交换数组迭代代码read
,这个问题可以修复:现在update
不需要知道MaxVal
,MaxVal
用于read
,并且我们可以使用最大的更新索引MaxVal
.
int read(int idx){
int sum = 0;
while (idx <= MaxVal){
sum += tree[idx];
idx += (idx & -idx);
}
return sum;
}
void update(int idx ,int val){
while (idx > 0){
tree[idx] += val;
idx -= (idx & -idx);
}
}
Run Code Online (Sandbox Code Playgroud)
笔记.
read
返回前缀sum)的实现不同,此实现提供后缀sum.如果您需要前缀sum,只需从值的总和中减去返回read
的值.BLSR
最近的英特尔指令集(BMI1))做得更好. 归档时间: |
|
查看次数: |
902 次 |
最近记录: |