20251027 倍增总结

引子

前缀和算法适用于静态区间和查询,通过预处理每个前缀和实现快速计算任意区间和。前缀和的两大局限在于无法处理不可减运算(如区间最值、GCD)和动态修改问题。每次动态修改会导致O(n)O(n)O(n)个前缀和需要更新,整体复杂度退化为O(n2)O(n²)O(n2)。对于不可减问题和动态问题,ST表和树状数组是更优选择。

倍增算法

倍增是ST表的基础,核心思想是通过递推预计算长度为1,2,4,...(2i≤n)1,2,4,...(2^i ≤ n)1,2,4,...(2in)的区间运算结果。每个位置需要预处理O(logn)O(logn)O(logn)个区间,整体构建复杂度为O(nlogn)O(nlogn)O(nlogn)。区间查询时,任意区间可拆分为最多lognlognlogn个预处理的倍增区间,利用二进制分解实现高效查询。

ST表

ST表适用于静态可重复贡献问题(如区间最值、GCD),特点是满足x与x运算结果仍为x。ST表预处理复杂度为O(nlogn)O(nlogn)O(nlogn),查询复杂度为O(1)O(1)O(1)。实现时需注意预处理对数表优化查询,将指数维度放在外层提高缓存命中率,并正确处理区间边界。

数学公式示例(区间最大值查询):

st[i][j]=max⁡(st[i][j−1],st[i+2j−1][j−1])\text{st}[i][j] = \max(\text{st}[i][j-1], \text{st}[i + 2^{j-1}][j-1])st[i][j]=max(st[i][j1],st[i+2j1][j1])

树状数组

树状数组支持单点修改和可减区间查询,基于lowbit运算实现。每个节点t[i]存储长度为lowbit(i)的区间和,前缀和可分解为至多lognlog nlogn个区间和。单点修改影响至多lognlog nlogn个区间,复杂度为O(logn)O(logn)O(logn)。实现时利用lowbit(x)=xlowbit(x)=xlowbit(x)=x&−x-xx快速定位相关区间,空间复杂度为O(n)O(n)O(n)

代码示例(树状数组基本操作):

int lowbit(int x){
	return x&-x;
}
void add(int i,int x){
	for(i;i<=n;i+=lowbit(i))s[i]+=x;
}
int sum(int i){
    int ans=0;
    for(i;i>=1;i-=lowbit(i)){
        ans+=s[x];
    }
    return ans;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值