我是靠谱客的博主 动听皮卡丘,最近开发中收集的这篇文章主要介绍【无标题】,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:

  1. C l r d,表示把 A[l],A[l+1],…,A[r] 都加上 d。
  2. Q l r,表示询问数列中第 l∼r 个数的和。

对于每个询问,输出一个整数表示答案。

输入格式

第一行两个整数 N,M。

第二行 N 个整数 A[i]。

接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围

1≤N,M≤105,
|d|≤10000,
|A[i]|≤109

输入样例:

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

输出样例:

4
55
9
15

树状数组维护区间加减区间求和的板子
设原前缀和数组是 sum[i]
一个树状数组 c0 维护与上一道题一样的数组 b[i] ,另一个树状数组 c1 维护 b[i]∗i
那么修改后第x个数的前缀和就是
sum[x]+(x−1)∗∑i=1xb[i]−∑i=1xb[i]∗i


sum[x]+(x−1)∗ask(c0,x)−ask(c1,x)
证明:
修改后第 x 个数的前缀和增加了
∑i=1x∑j=1ib[j]

=∑i=1x(x−i+1)∗b[i]

=(x+1)∑i=1xb[i]−∑i=1xi∗b[i]
 

维护第二个树状数组时,出现了一个令人困惑的点:
假设有一个操作C l r d,在维护第二个树状数组时只需要把位置 l 上的数加上 l∗d,位置 r+1 上的数减去 (r+1)∗d 就可以了。
当时我无法理解这样做的原因
但是我终于知道了
因为 c1 ,它根本就不是一个差分数组。
每次区间修改时,b[i]数组中只有 b[l] 和 b[r+1]发生改变,变化量分别为 +d, −d
故 b[i]∗i 数组中也只有 b[l]∗l 和 b[r+1]∗(r+1) 发生了变化,变化量分别为 d∗l,−d∗(r+1)
我们要的,只不过是 b[i]∗i 这个数组的前缀和而已
根本就不用在意前后是否抵消嘛!

最后

以上就是动听皮卡丘为你收集整理的【无标题】的全部内容,希望文章能够帮你解决【无标题】所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部