0

0

使用树状数组的前缀和数组更新,查询K的下界

王林

王林

发布时间:2023-09-04 17:33:04

|

1465人浏览过

|

来源于tutorialspoint

转载

使用树状数组的前缀和数组更新,查询k的下界

首要序列总和数组是一个集合,它累积交错元素的总和,直到达到特定的索引。这是一种广泛应用于组合重构以优化时间复杂度的策略。树状数组,也被称为二进制索引树(BIT),是一种高效地更新元素并在对数时间复杂度内计算前序列总和的数据库形式。

在本文中,我们将讨论如何使用C++中的Fenwick Tree进行现代化改进,以从一个系列求和数组中揭示给定值的较小极限边界,这个值被称为K。

语法

语法定义了两个函数,update和query,以及一个用于Fenwick树的主函数,Fenwick树是一种用于高效范围查询和更新操作的数据结构。update函数接受一个索引idx,一个值val,数组的大小n,以及Fenwick树数组BIT。它通过将val添加到索引idx及其所有祖先的节点来更新Fenwick树。query函数接受一个索引idx和Fenwick树数组BIT。它返回从根节点到索引idx的节点的累积和。主函数声明数组的大小n,前缀和数组arr,以及初始化为0的Fenwick树数组BIT。

void update(int idx, int val, int n, int BIT[]) {
   while (idx <= n) {
      BIT[idx] += val;
      idx += (idx & -idx);
   }
}
int query(int idx, int BIT[]) {
   int sum = 0;
   while (idx > 0) {
      sum += BIT[idx];
      idx -= (idx & -idx);
   }
   return sum;
}
// Driver code
int main() {
   int n; 
   int arr[n+1];
   int BIT[n+1] = {0}; 
   return 0;
}

算法

要确定带有Fenwick树更新的前缀和数组中K的最小值,请按照以下复杂的步骤进行 -

  • 实例化大小为 n+1 的 Fenwick 树 (BIT),将所有元素初始化为 0。

  • 使用 update() 函数修改具有给定前缀和数组的 Fenwick Tree。

  • 在Fenwick树上执行查询以确定K的下界。从n的二进制表示中的最高有效位开始迭代,直到最低有效位。使用query()函数验证当前前缀和是否小于或等于K。如果满足此条件,将当前前缀和从K中减去,并更新索引以移动到下一个位。如果不满足条件,则在不更新索引的情况下移动到下一个位。

  • 遍历完所有位后,索引将表示前缀和数组中 K 的下界。

  • 输出得到的索引作为K的下界。

    来福FM
    来福FM

    来福 - 你的私人AI电台

    下载

方法

  • 方法1 − 在Fenwick树上进行二分查找。在这种方法中,我们在Fenwick树上执行二分查找以找到K的下界。

  • 方法2 - 在Fenwick树上进行带有延迟传播的二分查找。

方法 1

为了解决这个问题,我们首先将左指针和右指针分别设置为1和n(表示前缀和数组的大小),然后采用二分查找策略来确定对应于小于或等于K的最大前缀和的索引i。然后,根据前缀和[i]的值是否小于或等于K,更新左指针或右指针的位置。

示例

这段代码的基本机制是利用了一种叫做 Fenwick Tree(也称为 Binary Indexed Tree)的数据结构。它的作用是在前缀和数组中确定指定值 'k' 的下界。这是通过使用更新函数构建 Fenwick Tree 来实现的,该函数将前缀和数组中每个元素的值合并到 Fenwick Tree 的相应位置中。

findLowerBound 函数然后采用二分搜索算法,通过查询函数来查明前缀和数组中“k”的下界。此函数计算直至 Fenwick 树中当前索引的值的累积和。最终,代码最终识别出前缀和数组中“k”下界的索引,并将结果显示到控制台。

#include 
using namespace std;
void update(int i, int v, int n, int b[]) {
    while (i <= n) {
        b[i] += v;
        i += (i & -i);
    }
}
int query(int i, int b[]) {
    int s = 0;
    while (i > 0) {
        s += b[i];
        i -= (i & -i);
    }
    return s;
}
int findLowerBound(int k, int n, int p[], int b[]) {
    int l = 1, r = n, idx = 0;
    while (l <= r) {
        int m = (l + r) / 2;
        int msum = query(m, b);
        if (msum <= k) {
            idx = m;
            l = m + 1;
        } else {
            r = m - 1;
        }
    }
    return idx;
}
int main() {
    int n = 5;
    int p[] = {0, 1, 3, 6, 10, 15};
    int b[n + 1] = {0};
    for (int i = 1; i <= n; i++) {
        update(i, p[i], n, b);
    }
    int k = 10, idx;
    idx = findLowerBound(k, n, p, b);
    cout << "The lower bound of " << k << " is at index " << idx << " in the prefix sum array." << endl;
    return 0;
}

输出

The lower bound of 10 is at index 3 in the prefix sum array.

方法2

为了进一步优化 Fenwick 树,可以采用一种称为惰性传播的技术。这种方法需要将对 Fenwick Tree 的更新推迟到实际需要时,从而减少更新次数并提高查询过程的效率。

示例

代码提供了一种解决方案,用于在前缀和数组中定位给定值K的下限。前缀和数组是一个数组,其中每个元素都是原始数组中从索引0到该索引的元素的总和。下限是前缀和数组中第一个使得到该索引的元素之和等于或超过K的索引。该解决方案使用Fenwick树数据结构和延迟传播技术来增强解决方案的效率。代码包括修改Fenwick树、计算前缀和和查找下限的函数。代码还初始化了前缀和数组、Fenwick树和延迟传播数组。最后,它输出了前缀和数组中K的下限。

#include  
#include  
using namespace std;

void update(int idx, int val, int n, int ft[], int lz[]) {
   while (idx  <= n) ft[idx] += val, idx += (idx & -idx);
}

int getPrefixSum(int idx, int ft[]) {
   int sum = 0;
   while (idx > 0) sum += ft[idx], idx -= (idx & -idx);
   return sum;
}

int findLowerBound(int K, int n, int ps[], int ft[], int lz[]) {
   int l = 1, r = n, lb = 0;
   while (l  <= r) {
      int m = (l + r) / 2, s = getPrefixSum(m, ft) + lz[m];
      if (s  <= K) lb = m, l = m + 1;
      else r = m - 1;
   }
   return lb;
}

int main() {
   int n = 5;
   int ps[] = {0, 1, 3, 6, 10, 15};
   int ft[n + 1], lz[n + 1]; memset(ft, 0, sizeof(ft)); memset(lz, 0, sizeof(lz));
   for (int i = 1; i  <= n; i++) update(i, ps[i] - ps[i - 1], n, ft, lz);
   int K = 10;
   int lb = findLowerBound(K, n, ps, ft, lz);
   cout << "For the given array with size " << n << " and prefix sum array [";
   for (int i = 1; i <= n; i++) {
      cout << ps[i];
      if (i < n) cout << ", ";
   }
   cout << "], the lower bound of " << K << " is at index " << lb << " in the prefix sum array." << endl;
   return 0;
}

输出

For the given array with size 5 and prefix sum array [1, 3, 6, 10, 15], the lower bound of 10 is at index 4 in the prefix sum array.

结论

关于从精心设计的前缀和数组中挖掘难以捉摸的 K 值阈值的讨论,并通过更新进行强化,利用 C++ 编程领域中巧妙的芬威克树算法。深入研究两种高效方法的复杂性:Fenwick 树上的二分搜索和带有惰性传播的 Fenwick 树上的二分搜索。根据您的特定难题的具体要求和限制,仔细选择最合适的方法。希望这能够阐明这一难以捉摸的任务的概念化和实现,即利用 C++ 领域中 Fenwick 树无与伦比的功能,从带有更新的前缀和数组中找到 K 的下界。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

534

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

16

2026.01.06

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

402

2023.08.14

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

346

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2074

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

347

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

255

2023.09.05

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

40

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 3.2万人学习

Excel 教程
Excel 教程

共162课时 | 12.1万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 2.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号