Introduction to Sequence Blocking 1 (LibreOj-6277)

Posted by webdzine on Tue, 30 Jul 2019 22:37:20 +0200

[Title Description]

Gives a long n sequence and N operations, which involve interval addition and single point search.

[Input Format]

The first line enters a number n.

The second line enters n digits, and the second digit is ai, separated by spaces.

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

If opt=0, it means that the numbers between [l,r] are all added c.

If opt=1, it means asking the value of a[r] (l and c are ignored).

[Output Format]

For each query, output a line of numbers to indicate the answer.

[Example]

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

[Data Scope and Tips]

For 100% data, 1<=n<=50000, -2^31<=other, ans<=2^31-1.

[Source Code]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 100000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;


int block;
int a[N],pos[N],tag[N];
void add(int L,int R,int x){
    for(int i=L;i<=min(pos[L]*block,R);i++)//Statistical Left Interval
        a[i]+=x;
    if(pos[L]!=pos[R])//If there is a right interval to traverse, avoid repeated calculation
        for(int i=(pos[R]-1)*block+1;i<=R;i++)//Statistical Right Interval
            a[i]+=x;
    for(int i=pos[L]+1;i<=pos[R]-1;i++)//Statistical Block Interval
        tag[i]+=x;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);

    block=sqrt(n);//Length of blocks
    for(int i=1;i<=n;i++)//The first element is in the block.
        pos[i]=(i-1)/block+1;

    for(int i=1;i<=n;i++){
        int op;
        int left,right,x;
        scanf("%d",&op);
        scanf("%d%d%d",&left,&right,&x);
        if(op==0)
            add(left,right,x);
        else
            printf("%d\n",a[right]+tag[pos[right]]);
    }
    return 0;
}