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

Choose react or angular 2

Original addressChoosing between React vs. Angular 2The following is the translation of this article, which can be used at your choiceReactperhapsAngular2We need to help when we need to. React has become a cool representative in 2015, but angular.js has changed from a front-end framework that people love to a terrible devil (and not so terrible…) […]