链接:https://www.nowcoder.com/acm/contest/135/I
来源:牛客网
题目描述
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]内的元素之和
示例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
在这个题目中我们可以使用差分数组与前缀和结合使用来的结果。
刚开始写的线段树,卡内存。。。。。然后通过大神指导(只有一次输出)。
那我们就可以把他们的me每一次改变的第一个位置(l)对应相应的改变。在r+1的位置取反这个改变。这样我们可以让每一次
a[i]改变的时候都可以同时加上c[i],最后利用前缀和思想,直接求差值。
代码:
#include<map>
#include<stack>
#include<bitset>
#include<math.h>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define fa ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
const int MAX_N=1000000+50;
const int INF=0x3f3f3f3f;
ll a[MAX_N]; //标记原始位置的数值
ll f[MAX_N]; //每次增加减少
int main()
{
fa;
memset(f,0,sizeof(f));
ll n,m;
a[0] = 0;
cin>>n>>m;
for(ll i = 1; i <= n; i++)
{
cin>>a[i];
}
ll q,l,r,p;
while(m--)
{
cin>>q>>l>>r>>p;
if(q == 1)
{
f[l] -= p;
f[r+1] += p;
}
else
{
f[l] += p;
f[r+1] -= p;
}
}
for(ll i = 1; i <= n; i++)
{
f[i] += f[i-1];
a[i] += a[i-1] + f[i];
}
cin>>l>>r;
cout<<a[r]-a[l-1]<<endl;
return 0;
}