题目描述 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

数据范围及提示 Data Size & Hint

数据范围

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(区间修改+区间查询)的更多相关文章

  1. 【codevs】1082 线段树练习 3 <区间修改+区间和>

    题目连接   http://codevs.cn/problem/1082/ Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. In ...

  2. 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询

    题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...

  3. 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

    题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不 ...

  4. 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询

    题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...

  5. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

  6. 1082 线段树练习 3 && 树状数组区间修改区间查询

    1082 线段树练习 3 题意: 给定序列初值, 要求支持区间修改, 区间查询 Solution 用树状数组, 代码量小, 空间占用小 巧用增量数组, 修改时在 \(l\) 处 $ + val$ , ...

  7. bzoj 3779 重组病毒 —— LCT+树状数组(区间修改+区间查询)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3779 RELEASE操作可以对应LCT的 access,RECENTER则是 makeroo ...

  8. 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 ...

  9. NOIP2017 列队 题解报告【56行线段树】

    题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...

随机推荐

  1. Github配置SSH

    以前也配置过ssh,但是没有注意用法,在配置一次熟悉流程 检查本机是否有ssh key设置 $ cd ~/.ssh 或cd .ssh 如果没有则提示: No such file or director ...

  2. 原来,表名和字段名不能在pdo中“参数化查询”

    https://stackoverflow.com/questions/182287/can-php-pdo-statements-accept-the-table-or-column-name-as ...

  3. 专题开发十二:JEECG微云高速开发平台-基础用户权限

      专题开发十二:JEECG微云高速开发平台-基础用户权限 11.3.4自己定义button权限 Jeecg中.眼下button权限设置,是通过对平台自己封装的button标签(<t:dgFun ...

  4. IE将開始屏蔽旧版ActiveX控件

    微软IE团队上周宣布将在IE中屏蔽旧版本号的ActiveX控件以加强IE的安全性.首先会被禁用的旧版本号ActiveX控件包括: J2SE 1.4, 低于update 43 的版本号 J2SE 5.0 ...

  5. 怎样免费设置QQ空间背景音乐

    怎样免费设置QQ空间背景音乐 1.打开QQ空间,点击 2. 3. 4.这里它要求我们输入歌曲的在线路径,并且必须是MP3格式的,这就简单了,我们仅仅要去网上找在线的MP3音乐就能够了.可是如今非常多提 ...

  6. Linux 简单的Shell输出

    echo:用于输出指定字符串或用于在Shell中打印Shell变量的值    语法格式:echo [选项] [参数]    -n:不输出换行 linlin@ubuntu:~/linlin/text$ ...

  7. Jedis学习使用(java操作redis)

    Jedis 是 Redis 官方首选的 Java client开发包. 工作过程总结的一个演示样例.贴出来,例如以下: package com.wujintao.redis; import java. ...

  8. github远程仓储和本地仓储进行关联

    我们使用github作为远程仓储,需要提前注册号一个github账号 由于github仓储和本地仓储之间传输是使用ssh加密的,所以需要一点设置, 1.创建sshkey  gitbash执行: ssh ...

  9. Dos下同时执行多条命令简化操作

    起因,要查询8080端口被哪些程序占用了,但是直接在cmd netstat –ano 的话 一下子一大把数据出来了不利于查找, 于是就想起dos下可以同时指向多条命令,如是写下如下命令: netsta ...

  10. Restrictions.or多个条件用法

    两个条件或查询: Restrictions.or(Restrictions.in("username",list1),Restrictions.idEq(1)); 三个或多个条件查 ...