链接: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]内的元素之和
思路:
我们知道了要进行M次操作和左后所要查找的区间范围【l,r】不如先把所有区间存起来,然后从后往前一一处理这些范围加减的数,为了避免超时,我在处理【l,r】的原数的和的时候用了下前缀和(不用应该也没关系反正O(n)的复杂度)。
完整代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
int N,M;
struct node
{
int q,l,r,p;
}ti[1000002];
ll a[1000002];
int L,R;
ll panp(int x)
{
if(x==1) return (-1);
else return 1;
}
int main()
{
while(scanf("%d%d",&N,&M)!=EOF)
{
memset(a, 0, sizeof(a));
for(int i=1; i<=N; i++)
{
scanf("%lld",&a[i]);
a[i]+=a[i-1];
}
for(int i=1; i<=M; i++)
{
scanf("%lld%lld%lld%lld", &ti[i].q, &ti[i].l, &ti[i].r, &ti[i].p);
}
scanf("%d%d",&L,&R);
ll sum=a[R]-a[L-1];
for(int i=1; i<=M; i++)
{
if(ti[i].l<=L && ti[i].r<=R && ti[i].r>=L)
{
sum=sum+(ti[i].r-L+1)*panp(ti[i].q)*ti[i].p;
}
else if(ti[i].l<=L && ti[i].r>=R)
{
sum=sum+(R-L+1)*panp(ti[i].q)*ti[i].p;
}
else if(ti[i].l>=L && ti[i].r<=R)
{
sum=sum+(ti[i].r-ti[i].l+1)*panp(ti[i].q)*ti[i].p;
}
else if(ti[i].r>=R && ti[i].l<=R)
{
sum=sum+(R-ti[i].l+1)*panp(ti[i].q)*ti[i].p;
}
}
printf("%lld\n",sum);
}
return 0;
}