区间 (interval)
牛客小白月赛5 I 区间 (interval)
题目:
链接: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]内的元素之和
思路:
数组a保存每个数
数组cha记录每一个数和前一位的差,区间(l,r)加上x: 区间首端 cha[l] 加上x, 区间尾端+1位置cha[r+x]减去x
对cha求前缀和得出所有区间修改操作后,每个位置的数
再求一次前缀和,得出答案
代码:
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; ll a[1100000],cha[1100000]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); cha[i]=a[i]-a[i-1]; //求差分序列 } while(m--){ int q,l,r,p; scanf("%d%d%d%d",&q,&l,&r,&p); if(q==1)p=-p; cha[l]+=p; cha[r+1]-=p; } ///得到操作后的每个数 for(int i=1;i<=n+7;i++){ cha[i]+=cha[i-1]; } ///求前缀和 for(int i=1;i<=n+7;i++){ cha[i]+=cha[i-1]; } int l,r; scanf("%d%d",&l,&r); printf("%lld\n",cha[r]-cha[l-1]); return 0; }