分块做题记录-----数列分块入门 1
Description
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。
Input
第一行输入一个数字 n。 第二行输入 n 个数字,第 i 个数字为 ai,以空格隔开。 接下来输入 n行询问,每行输入四个数字 opt、l、r、c,以空格隔开。 若 opt=0,表示将位于 [l,r]的之间的数字都加 c。 若 opt=1,表示询问 ar 的值(l 和 c 忽略)。 1≤n≤50000,-2^31 ≤others、ans≤2^31-1
Output
对于每次询问,输出一行一个数字表示答案。
Sample Input
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
Sample Output
2
5
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int N=5e4+5; 7 int n,blo; 8 int v[N],bl[N],tag[N]; 9 void add(int a,int b,int c) 10 { 11 for(int i=a; i<=min(bl[a]*blo,b); i++) 12 v[i]+=c; 13 if(bl[a]!=bl[b]) 14 for(int i=(bl[b]-1)*blo+1; i<=b; i++) 15 v[i]+=c; 16 for(int i=bl[a]+1; i<=bl[b]-1; i++) 17 tag[i]+=c; 18 } 19 int main() 20 { 21 scanf("%d",&n); 22 blo=sqrt(n); 23 for(int i=1; i<=n; i++) 24 { 25 scanf("%d",&v[i]); 26 bl[i]=(i-1)/blo+1; 27 } 28 for(int i=1; i<=n; i++) 29 { 30 int f,a,b,c; 31 scanf("%d%d%d%d",&f,&a,&b,&c); 32 if(f==0)add(a,b,c); 33 else printf("%d\n",v[b]+tag[bl[b]]); 34 } 35 return 0; 36 }