牛客网小白月赛5I区间(差分数组)

时间:2023-03-09 20:15:15
牛客网小白月赛5I区间(差分数组)

链接:https://www.nowcoder.com/acm/contest/135/I
来源:牛客网

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

Apojacsleam喜欢数组。

他现在有一个n个元素的数组a,而他要对a[L]-a[R]进行M次操作:

操作一:将a[L]-a[R]内的元素都加上P

操作二:将a[L]-a[R]内的元素都减去P

    最后询问a[l]-a[r]内的元素之和?
    请认真看题干及输入描述。

输入描述:

输入共M+3行:

第一行两个数,n,M,意义如“题目描述”

第二行n个数,描述数组。

第3-M+2行,共M行,每行四个数,q,L,R,P,若q为1则表示执行操作2,否则为执行操作1

第4行,两个正整数l,r

输出描述:

一个正整数,为a[l]-a[r]内的元素之和

输入例子:
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5 5
1 2 3 6
0 2 5 5
0 2 5 8
1 4 9 6
2 7
输出例子:
23

-->

示例1

输入

复制

10 5
1 2 3 4 5 6 7 8 9 10
1 1 5 5
1 2 3 6
0 2 5 5
0 2 5 8
1 4 9 6
2 7

输出

复制

23

说明

牛客网小白月赛5I区间(差分数组)
解题思路:这个题目用暴力应该很简单,但是很明显肯定会超时。看了别人的题解好像都是用前缀和加上差分数组或者线段树,觉得用差分数组前缀和简单点,首先设一个add数组用来存每个位置的变化值,先清0,假如是修改[l,r]区间,该区间每个数加p的话,add[l]+=p,add[r+1]-=p,当然m次操作完了之后,此时add[i]还不是a[i]的变化值,要求a[i]的变化值,需要求add数组的前缀和,求完之后add[i]即是代表了a[i]的变化值了,对add数组和a数组同时求区间和就是a[l]-a[r]内的元素之和。
 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
int n,m,tl,tr,q,l,r,p;
int a[maxn],add[maxn]; int main()
{
memset(add,,sizeof(add));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",a+i);
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&q,&l,&r,&p);
if(q==)
{
add[l]-=p;
add[r+]+=p;
}
else
{
add[l]+=p;
add[r+]-=p;
}
}
scanf("%d%d",&tl,&tr);
ll sum=;
for(int i=;i<=n;i++)
add[i]+=add[i-];
for(int i=tl;i<=tr;i++)
sum+=a[i]+add[i];
printf("%lld\n",sum);
return ;
}