分块板子

昨天写完分块,发现自己写的不行,上网搜了一下分块板子,不大一样(但自我感觉逻辑一样),又学了一遍,今天写了写,主要来发个分块板子(求和的)。

#include<iostream>
#include<cmath>
using namespace std;
int n,m;
int ge,shu;
int a[1000010],belong[1000010];
int s[1010],tag[1010];
int l[1010],r[1010];
void build(){
    for(int i=1;i<=n;i++){
        belong[i]=(i-1)/ge+1;
        s[belong[i]]+=a[i];
    }
    for(int i=1;i<=shu;i++){
        l[i]=(i-1)*ge+1;
        r[i]=i*ge;
    }
    r[shu]=n;
}
void change(int x,int y,int k){
    if(belong[x]==belong[y]){
        for(int i=x;i<=y;i++){
            a[i]+=k;
            s[belong[i]]+=k;
        }
    }
    else{
        for(int i=x;i<=r[belong[x]];i++){
            a[i]+=k;
            s[belong[i]]+=k;
        }
        for(int i=l[belong[y]];i<=y;i++){
            a[i]+=k;
            s[belong[i]]+=k;
        }
        for(int i=belong[x]+1;i<=belong[y]-1;i++){
            tag[i]+=k;
            s[belong[i]]+=k*ge;
        }
    }
}
void cha(int x,int y){
    int sum=0;
    if(belong[x]==belong[y]){
        for(int i=x;i<=y;i++){
            sum+=a[i]+tag[belong[i]];
        }
    }
    else{
        for(int i=x;i<=r[belong[x]];i++){
            sum+=a[i]+tag[belong[i]];
        }
        for(int i=l[belong[y]];i<=y;i++){
            sum+=a[i]+tag[belong[i]];
        }
        for(int i=belong[x]+1;i<=belong[y]-1;i++){
            sum+=s[i];
        }
    }
    cout<<sum<<endl;
}
int main(){
    cin>>n>>m;
    ge=sqrt(n);
    shu=n/ge;
    if(n%ge!=0){
        shu++;
    }
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build();
    for(int i=1;i<=m;i++){
        int c,x,y,k;
        cin>>c;
        if(c==1){
            cin>>x>>y>>k;
            change(x,y,k);
        }
        else{
            cin>>x>>y;
            cha(x,y);
        }
    }
    return 0;
} 

 

posted @ 2022-02-10 16:06  zzzzzz2  阅读(45)  评论(0编辑  收藏  举报