题解报告:CODE[VS] 1082 线段树练习3(区间修改+区间查询)
题目描述 Description
给你N个数,有两种操作:
1:给区间[a,b]的所有数增加X
2:询问区间[a,b]的数的和。
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,
再接下来一个正整数Q,每行表示操作的个数,
如果第一个数是1,后接3个正整数,
表示在区间[a,b]内每个数增加X,如果是2,
表示操作2询问区间[a,b]的和是多少。
pascal选手请不要使用readln读入
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 2 3
样例输出 Sample Output
9
数据范围
1<=n<=200000
1<=q<=200000
解题思路:题目虽然写的是线段树,但是很多情况下树状数组都可以代替线段树来做,而且有一个很明显的优点就是树状数组的代码要比线段树简洁得多,因此拿这道题作为树状数组区间修改+区间查询入门最好不过了!(这里不涉及线段树代码,不会线段树的另百度自学)上一篇博文里讲到用差分数组实现区间修改,但是怎么实现区间查询呢?联系单点查询求前缀和公式易得求区间[1,p]内所有元素和的公式:
。从中可以发现:等式右边的式子中d[1]被加了p次,d[2]被加了p-1次...,于是位置p的前缀和公式为:
,将其展开可以得到a[1]+a[2]+...+a[p]=(d[1])+(d[1]+d[2])+...+(d[1]+d[2]+...+d[p])=p*(d[1]+d[2]+...+d[p])-(0*d[1]+1*d[2]+...+(p-1)*d[p]),看到没,是不是和单点查询树状数组维护差分数组一样?接下来我们只需用两个树状数组来维护一下两个差分数组:sum1[i]=d[i],sum2[i]=(i-1)*d[i]。区间修改:假设将区间[l,r]中每个元素加上k,则只需在两个树状数组上进行修改:sum1[l]+=k,sum1[r+1]-=k,sum2[l]+=(l-1)*k,sum2[r+1]-=r*k,然后区间[1,p]的求和公式(区间查询)就为p*get_sum(sum1,p)-get_sum(sum2,p)。以上所有操作的时间复杂度均为O(nlogn),显然比线段树快且简洁多了。
AC代码(542ms):
/*
作者:霜雪千年
题目:p1082 线段树练习 3
*/ #include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=2e5+;
LL n,l,r,k,q,p,val[maxn],sum1[maxn],sum2[maxn];
void add(LL *sum,LL x,LL val){
while(x<=n){sum[x]+=val;x+=(x&-x);}
}
LL get_sum(LL *sum,LL x){
LL ans=;
while(x>){ans+=sum[x];x-=(x&-x);}
return ans;
}
LL ask(LL x){
return x*get_sum(sum1,x)-get_sum(sum2,x);
}
int main(){
while(~scanf("%lld",&n)){
memset(sum1,,sizeof(sum1));//注意清0
memset(sum2,,sizeof(sum2));
memset(val,,sizeof(val));
for(LL i=;i<=n;++i){
scanf("%lld",&val[i]);
add(sum1,i,val[i]-val[i-]);//维护两个差分数组
add(sum2,i,(i-)*(val[i]-val[i-]));
}
scanf("%lld",&q);
while(q--){
scanf("%lld",&p);
if(p==){
scanf("%lld%lld%lld",&l,&r,&k);
add(sum1,l,k),add(sum1,r+,-k);//区间修改
add(sum2,l,(l-)*k);add(sum2,r+,-r*k);
}
else{
scanf("%lld%lld",&l,&r);
printf("%lld\n",ask(r)-ask(l-));//区间查询[1,r]-[1,l-1]=[l,r]
}
}
}
return ;
}
题解报告:CODE[VS] 1082 线段树练习3(区间修改+区间查询)的更多相关文章
- 【codevs】1082 线段树练习 3 <区间修改+区间和>
题目连接 http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...
- 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询
题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...
- 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询
题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不 ...
- 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询
题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...
- 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询
题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...
- 1082 线段树练习 3 && 树状数组区间修改区间查询
1082 线段树练习 3 题意: 给定序列初值, 要求支持区间修改, 区间查询 Solution 用树状数组, 代码量小, 空间占用小 巧用增量数组, 修改时在 \(l\) 处 $ + val$ , ...
- bzoj 3779 重组病毒 —— LCT+树状数组(区间修改+区间查询)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 RELEASE操作可以对应LCT的 access,RECENTER则是 makeroo ...
- HDU-3974 Assign the task题解报告【dfs序+线段树】
There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...
- NOIP2017 列队 题解报告【56行线段树】
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...
随机推荐
- 【python】对象和面向对象
类的定义 python支持多重继承,在类名后面的小括号中,可以列出多个类名,以逗号分割. __init__方法在类的实例创建后被立即调用,注意与c++中构造函数不一样,因为对象在调用__init__时 ...
- Wi-Fi无线网络(WPA2加密)快速破解 ——某公司无线设备安全隐患报告
Wi-Fi无线网络(WPA2加密)快速破解 --某公司无线设备安全隐患报告 评估人:阿牛 2013年12月12日 文件夹 一. 导言 2 二. 背景 2 三. 无线产品应当採取的安全策略 3 四. 存 ...
- Android进阶图片处理之三级缓存方案
图片的三级缓存 一.概述 一開始在学习Android的时候.处理图片的时候,每次获取图片都是直接从网络上面载入图片. 可是在开发项目的过程中,每次点击进入app里面,图片都要慢慢的再一次从网络上面载入 ...
- Orange's_1_win7下搭建环境
工欲善其事,必先利其器. 由于公司电脑工作环境是win7,为了学习于渊的Orange,所以就在windows下配置环境: 1.nasm: nasm汇编 http://www.nasm.us/ ...
- 基于websocket的单聊.群聊
关于ai.baidu.com的 代码: #########################################核心代码################################### ...
- 第一个WordCount类运行
import java.io.IOException; import java.util.*; import org.apache.hadoop.fs.Path; import org.apache. ...
- brctl和虚拟网桥
1 创建空的虚拟网桥 brctl addbr br0 这个时候可以认为该虚拟网桥有多个虚拟接口,但是没有实际的网卡接口和该虚拟网桥相连的. 2 将eth0网卡连接到br0 网卡只有一个接口,这个接口是 ...
- 内存溢出-jvisualvm排查问题
先来一段能够内存溢出的程序 public static void main(String[] args) { List<Object> list = new ArrayList<&g ...
- u-boot支持LCD显示(基于TQ2440)【转】
本文转载自:http://www.cnblogs.com/pengdonglin137/p/4633877.html u-boot支持LCD显示(基于TQ2440) 阅读目录(Content) 平 ...
- YTU 2891: E--围栏
2891: E--围栏 时间限制: 1 Sec 内存限制: 128 MB 提交: 91 解决: 24 题目描述 一串连续字符被称作围栏当且仅当它由间隔的'|'和'-'组成.比如"|-|- ...