题目描述
给出一个长为 的数列,以及 个操作,操作涉及区间加法,区间求和。
输入格式
第一行输入一个数字 。
第二行输入 个数字,第 个数字为 ,以空格隔开。
接下来输入 行询问,每行输入四个数字 ,以空格隔开。
若 ,表示将位于 的之间的数字都加 。
若 ,表示询问位于 的所有数字的和 。
1 #include <cstdio> 2 #include<iostream> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 #define ll long long 7 ll n; 8 ll B; 9 ll a[50005],belong[50005],tag[50005]; 10 ll opt,l,r,c; 11 inline void prework(){ 12 ll B=sqrt(n); 13 for (ll i = 1;i <= n;i++){ 14 scanf ("%lld",&a[i]); 15 belong[i]=(i-1)/B+1; 16 } 17 } 18 inline void add(ll l,ll r,ll c){ 19 ll bl=belong[l]+1, br=belong[r]-1; 20 for (ll i = bl;i <= br;i++) tag[i]+=c; 21 if (belong[l]==belong[r]) 22 { 23 for (ll i = l;i <= r;i++) a[i]+=c; 24 } 25 else { 26 for (ll i = l;belong[i]!=bl;i++) a[i]+=c; 27 for (ll i = r;belong[i]!=br;i--) a[i]+=c; 28 } 29 } 30 inline ll query(ll q){ 31 return a[q]+tag[belong[q]]; 32 } 33 int main() 34 { 35 scanf ("%lld",&n); 36 prework(); 37 B=sqrt(n); 38 for (ll i = 1;i <= n;i++){ 39 scanf ("%lld%lld%lld%lld",&opt,&l,&r,&c); 40 if (opt==1){ 41 printf ("%lld\n",query(r)); 42 } 43 else{ 44 add(l,r,c); 45 } 46 } 47 return 0; 48 }