分块九题 --- 1

题目

题解

本蒟蒻要开始学分块了,区间查询神器,区间修改单点查询。

代码

#include<bits/stdc++.h>

using namespace std;
const int MAXN = 50005;
const int N = 305;

inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*f;
}

int n,a[MAXN];
int bl[MAXN];  //标记属于哪个块
int l[N],r[N];   //标记块的边界
int num;  //块的个数
int in[N];  //加法标记 
int siz; //块的大小 

inline void build(){
    siz=sqrt(n);
    num=n/siz;
    if(n%siz) num++;
    for(register int i=1;i<=num;i++){
        l[i]=(i-1)*siz+1;
        r[i]=i*siz;
    }
    for(register int i=1;i<=n;i++)
        bl[i]=(i-1)/siz+1;
    r[num]=n;
}

inline void update(int ql,int qr,int w){
    if(bl[ql]==bl[qr]){
        for(register int i=ql;i<=qr;i++)
            a[i]+=w;
        return;
    }
    for(register int i=ql;i<=r[bl[ql]];i++)
        a[i]+=w;
    for(register int i=bl[ql]+1;i<=bl[qr]-1;i++)    
        in[i]+=w;
    for(register int i=l[bl[qr]];i<=qr;i++)
        a[i]+=w;
}

inline int query(int qr){
    return a[qr]+in[bl[qr]];
}

int main(){
    n=rd();
    for(register int i=1;i<=n;i++)
        a[i]=rd();
    build();
    for(register int i=1;i<=n;i++){
        int op,L,R,k;
        op=rd();L=rd();R=rd();k=rd();
        if(op==0)
            update(L,R,k);
        else
            printf("%d
",query(R));
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/sdfzsyq/p/9677037.html