数列分块--数列分块入门1

题目描述

给出一个长为 的数列,以及 个操作,操作涉及区间加法,区间求和。

输入格式

第一行输入一个数字

第二行输入 个数字,第 个数字为 ,以空格隔开。

接下来输入 行询问,每行输入四个数字 ,以空格隔开。

,表示将位于 的之间的数字都加

,表示询问位于 的所有数字的和

 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 }

猜你喜欢

转载自www.cnblogs.com/very-beginning/p/12263035.html
今日推荐