Block basics (simple and easy to understand)

Block

Blocking is considered to be elegant violence, mainly for the question of interval.

Blocking means dividing a segment into many blocks,

We usually use x=sqrt(n) to represent the size of a block

num = ceil (n × \ times× 1.0/x) to indicate the number of blocks

The main requirement for chunking is 3 arrays,

pos[i] is to indicate the block where the i-th number is located

l[i] represents the left endpoint of the i-th block

r[i] represents the right endpoint of the i-th block

For example, the following question

We have to create another ans[i] array to represent the number we added to the i-th block.

But this gave birth to a question, if the i-th block included in the added interval is incomplete, can we put c on ans[i],

The answer is no.

For incomplete blocks, we should violently solve them by adding c to the a array, that is, the original array

For the complete block, we only need to add c to the ans array

So the final result is that the size of the i-th number is a[i]+ans[pos[i]]

Title description

Given a sequence of length n and n operations, the operations involve interval addition and single-point lookup.

Input format

Enter a number on the first line. Enter n numbers in the second line , and the i- th number is a[i] , separated by spaces.

Next, enter n lines of inquiry, each line enter four numbers opt, l, r, c separated by spaces,

If opt=0 means to add c to all the numbers between [l,r].

If opt=1 , it means asking for the value of a[r]

Output format

For each query, output a number on a line to indicate the answer.

Sample

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
#include<bits/stdc++.h>
using namespace std;
int l[2005],r[2005] ,pos[50005],a[50005],ans[50005];
void add(int ll,int rr,int v)
{
	int posl=pos[ll];
	int posr=pos[rr];
	if(posr-posl<=1)/*这个表示要加的区间在一个块内,即直接在原数组a上加*/
	{
		for(int i=ll;i<=rr;i++)
		{
			a[i]=a[i]+v;
		}
		
	}
	else
	{
		for(int i=ll;i<=r[posl];i++)/*前面的不完整的块*/
		a[i]=a[i]+v;
		for(int i=pos[ll]+1;i<pos[rr];i++)/*完整的块*/
		ans[i]+=v;
		for(int i=l[posr];i<=rr;i++)/*后面不完整的块*/
		a[i]=a[i]+v;
	}
	
}
void shuchu(int rr)
{
	if(ans[pos[rr]])
	printf("%d\n",a[rr]+ans[pos[rr]]);
	else
	printf("%d\n",a[rr]);
}
int main()
{
	int n;
	int opt ,ll,rr,cc;
	cin>>n;
	int x=sqrt(n);
	int num=ceil(n*1.0/x);
	for(int i=1;i<=num;i++)/*预处理l和r 数组*/
	{
		l[i]=(i-1)*x+1;
		r[i]=i*x;
	}
	r[num]=n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		pos[i]=(i-1)/x+1;	/*处理pos数组*/
	}
	for(int i=1;i<=n;i++)
	{
		cin>>opt>>ll>>rr>>cc;
		if(opt==0)
		{
			add(ll,rr,cc);
		}
		else
		{
			shuchu(rr);
		}
		
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/hhuhgfhggy/article/details/108978595