Special topic – sequence block 2

Time:2020-12-5

Series block topic No.2

Block application and promotion
If you don’t know how to block, please learn “block 1” first->Click here to learn

Put on question number – LOJ 6278 block entry 2
Link up- https://loj.ac/problem/6278
Question surface – give a sequence of numbers, 2 operations, interval addition and ask the number of elements less than a certain value in the interval

Now, get to the point

The difference between this question and that of block 1 is that the single point query becomes an interval query for the number of elements less than a certain value

It’s very difficult. The sequence is out of order. If you compare one by one, O (n ^ 2) will definitely exceed the time limit. If you disrupt the original order, you can’t find the given range of the topic

At this time, the block was put into use again, and the core idea of “large section maintenance, small section simplicity” is still the same

But how to “maintain large sections”? Since we can’t sort the entire sequence, we might as well sort each block. Look at the data. At 50000 level, the sort of O (n * logn) can meet the demand.

void reset(int x){
    ve[x].clear();
    for(int i=(x-1)*blo+1;i<=min(x*blo,N);i++)
        ve[x].push_back(v[i]);
    sort(ve[x].begin(),ve[x].end());
    //For a block modification and sorting (since the elements in the vector cannot be modified, they are reset and then put in again) 
}

After sorting, it is clear that for each block, we use o (logn) binary search (lower)_ Bound function) to find the number of elements less than a certain value.

for(int i=bl[a]+1;i<=bl[b]-1;i++){
    Int x = c-atag [i]; // first subtract the interval unified amount, reflecting the micro promotion macro 
    ans+=lower_ Bound (VE [i]. Begin(), ve [i]. End(), x) - ve [i]. Begin(); // binary search for quantity 
}

“Simple paragraph” means that the head and tail are less than a block, and the method of comparison is used one by one

for(int i=a;i<=min(bl[a]*blo,b);i++)
    if(v[i]+atag[bl[a]]<c)
        ans++;
    
if(bl[a]!=bl[b])
    for(int i=(bl[b]-1)*blo+1;i<=b;i++)
        if(v[i]+atag[bl[b]]<c)
            ans++;

Interval addition is basically the same as before. If you don’t know, you can refer to “sequence block 1”->Click here to learn
But remember to sort after “segment maintenance”

for(int i=a;i<=min(bl[a]*blo,b);i++)
    v[i]+=c;
Reset (BL [a]); // after a single point of modification is made in the "small section", remember to sort the block modifications 
    
if(bl[a]!=bl[b]){
    for(int i=(bl[b]-1)*blo+1;i<=b;i++)
        v[i]+=c;
    Reset (BL [b]); // the same thing 
}

Here is the end of the basic ~ finally attached with the complete code (c + +) and carefully designed comments

//LOJ 6278 - sequence block exercise 2
// https://loj.ac/problem/6278
//Vector 

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int N,blo;
int v[50005],bl[50005],atag[50005];
vector<int> ve[505];

void reset(int x){
    ve[x].clear();
    for(int i=(x-1)*blo+1;i<=min(x*blo,N);i++)
        ve[x].push_back(v[i]);
    sort(ve[x].begin(),ve[x].end());
    //For a block modification and sorting (since the elements in the vector cannot be modified, they are reset and then put in again) 
}

void add(int a,int b,int c){
    for(int i=a;i<=min(bl[a]*blo,b);i++)
        v[i]+=c;
    Reset (BL [a]); // after a single point of modification is made in the "small section", remember to sort the block modifications 
    
    if(bl[a]!=bl[b]){
        for(int i=(bl[b]-1)*blo+1;i<=b;i++)
            v[i]+=c;
        Reset (BL [b]); // the same thing 
    }
    
    for(int i=bl[a]+1;i<=bl[b]-1;i++)
        atag[i]+=c;
}

int query(int a,int b,int c){
    int ans=0;
    for(int i=a;i<=min(bl[a]*blo,b);i++)
        if(v[i]+atag[bl[a]]<c)
            ans++;
    //On the left, there is less than one piece of "simplicity" 
    
    if(bl[a]!=bl[b])
        for(int i=(bl[b]-1)*blo+1;i<=b;i++)
            if(v[i]+atag[bl[b]]<c)
                ans++;
    //Right 
    
    for(int i=bl[a]+1;i<=bl[b]-1;i++){
        Int x = c-atag [i]; // first subtract the interval unified amount, reflecting the micro promotion macro 
        ans+=lower_ Bound (VE [i]. Begin(), ve [i]. End(), x) - ve [i]. Begin(); // binary search for quantity 
    }
    
    return ans;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> N;
    blo=sqrt(N);
    
    for(int i=1;i<=N;i++)
       cin >> v[i];
    
    for(int i=1;i<=N;i++){
        bl[i]=(i-1)/blo+1;
        ve[bl[i]].push_back(v[i]);
    }
    
    for(int i=1;i<=bl[N];i++)
        sort(ve[i].begin(),ve[i].end());
    
    for(int i=1;i<=N;i++){
        int F, L, R, C;
        cin >> F >> L >> R >> C;
        If (F = = 0) add (L, R, c); // interval addition 
        If (F = = 1) cout < < query (L, R, c * c) < endl; // interval query 
    }
    
    return 0;
}

If you have any questions, please put them in the comments section below

Recommended Today

SDS of redis data structure

SDS(simple dynamic string), simple dynamic string. S and it’s called hacking string. Where hack is stored is the length of the string and the remaining space in SDS. The implementation of SDS insds.cIn the middle. C language string uses a character array of length N + 1 to represent the string of length N, and […]