Arithmetic(线段树维护历史版本和)

本文介绍了一种在线段树上维护历史版本区间和的方法,用于解决多重集合在给定公差d下的等差数列价值和查询。通过双指针和单调栈求解可行区间,同时使用线段树进行区间加减操作。在处理区间价值和的累计时,引入了tag和addh两种标记,确保了正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:一个多重集合的价值为将其变为公差为ddd(将在第一行输入)的等差数列需要插入几个数字(无法实现价值为0)。多次询问l,rl,rl,r,求[l,r][l,r][l,r]的子区间的价值和。
序列长度3e53e53e5,数字大小和d≤1e7d\leq 1e7d1e7

首先对于r′>rr'>rr>rlll使得[l,r][l,r][l,r]是最长的可以实现的区间,l′l'l是使得[l′,r′][l',r'][l,r]是最长的可以实现的区间,那么l′≥ll' \geq lll,所以我们可以用双指针扫一遍求出所有可以实现的区间在哪些区间内。
那么对于所有可以实现的区间,我们有一个简单的方法可以计算一个区间[l,r][l,r][l,r]构成的集合的价值:
最大值d−最小值d+l−r\frac {最大值}d - \frac {最小值}d + l - rdd+lr
然后就是很套路的在双指针的同时维护两个单调栈,在栈中发生插入和删除操作的同时在线段树上区间加减。
那么如果我们问的是[l,r][l,r][l,r]的价值,离线后就是双指针右端点到达rrr时,单点查询lll.
如果问的是∑i=lr[i,r]\sum_{i=l}^r [i,r]i=lr[i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值