标签:le limits 分块 sum sqrt mathcal 杂题
[洛谷T205310] practiceZ
给定两个长为 \(n\) 的序列 \(a,b\),支持三种操作:
1 l r x
:将 \(a\) 序列中区间 \([l,r]\) 的数赋值为 \(x\);2 l r y
:将 \(b\) 序列中区间 \([l,r]\) 的数赋值为 \(y\);3 l r
:求 \(\sum\limits_{i=l}^{r} \sum\limits_{j=1}^{b_i}a_j\),答案对 \(2^{32}\) 取模。\(1\le n\le 5\cdot 10^5,1\le m\le 3\cdot 10^5\)。
时间限制 \(\text{5000ms}\),空间限制 \(\text{128MB}\)。
Solution
考虑将 \(b\) 序列分块,我们的目的是时刻维护块内 \(\sum\limits_{i} \sum\limits_{j=1}^{b_i}a_j\),即答案。
先不考虑 2
操作。我们用珂朵莉树维护 \(a\) 序列的连续段,连续段是均摊 \(\mathcal O(n+q)\) 条,它对一个块的影响是 \(\Delta \times \sum\limits_{i=l}^{r} (块内有多少个 b_j \ge i)\),右边拆式子就是 \(\sum\limits_{i=1}^{r} (块内有多少个 b_j\ge i)-\sum\limits_{i=1}^{l-1} (块内有多少个 b_j\ge i)\)。因为有 $\mathcal O(\sqrt{n}) $ 个块,所以我们需要支持一个 \(\mathcal O(1)\) 求这玩意的 DS:
因此,我们对于每个块,开两个分块,一个维护 \(b\) 值域前缀和,一个维护 \(b\) 值域后缀个数和即可。
查询的时候,对于整块直接拿答案,散块暴力查,所以我们还需要对 \(a\) 支持一个 \(\mathcal O(\sqrt{n})\) 区间加,\(\mathcal O(1)\) 前缀查的 DS,用分块即可。
现在考虑加上 2
操作。我们再开一个珂朵莉树维护 \(b\) 序列的连续段,连续段内的 \(\sum\limits_{i=1}^{b} a_j\) 是一样的,连续段同样均摊 \(\mathcal O(n+q)\) 条。2
操作,它会影响到原本块内维护的这两个分块,但是都是单点修改,所以我们只要能对这个分块进行 \(\mathcal O(\sqrt{n})\) 修改即可,这个不难。对于整块直接覆盖答案即可,对于散块,重构影响到的位置的答案即可。
现在我们能做到时间复杂度 \(\mathcal O((n+q)\sqrt{n})\),空间复杂度 \(\mathcal O(n\sqrt{n})\),空间承受不了。我们可以采用逐块处理的方式,把所有 \(a,b\) 珂朵莉树的连续段全部存下来,然后对于每一块分别扫即可。
在逐块处理的时候,有一个比较棘手的问题,就是对 \(a\) 维护的分块,在每个块都要重新再做一遍,这样就变成暴力了。我们考虑在啥时候要用到它:
- 在查询时,散块的地方用到;
- 在
2
操作导致的 \(b\) 连续段,查询 \(\sum\limits_{i=1}^{newb} a_i\) 用到。
第一个,我们在离线前就可以提前计算贡献;第二个,我们把这玩意存下来,离线的时候就可以直接获取。这样,该问题就解决了。
时间复杂度 \(\mathcal O((n+q)\sqrt{n})\),空间复杂度 \(\mathcal O(n)\)。
标签:le,limits,分块,sum,sqrt,mathcal,杂题 来源: https://www.cnblogs.com/wlzhouzhuan/p/15707454.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。