首页 > 其他 > 详细

[知识学习] 分块

时间:2020-01-14 17:51:15      阅读:76      评论:0      收藏:0      [点我收藏+]

贴个板子,供自己看

分块核心:暴力操作

左端不完整区间,右端不完整区间暴力计算

中间完整区间lazy标记

#include <bits/stdc++.h>
#define N (100000+5)
using namespace std;
int n,k,a[N],lazy[N],pos[N],L[N],R[N];//a原数组,lazy懒标记,pos[i]:i对应的块,L[i]:块i的左端点,R[i]:块i的右端点
void add(int l,int r,int c){//区间加
    for(int i=l;i<=min(R[pos[l]],r);i++){//左端不完整区间处理
        a[i]+=c;
    }
    if(pos[l]!=pos[r]){
        for(int i=L[pos[r]];i<=r;i++){//右端不完整区间处理
            a[i]+=c;
        }
    }
    for(int i=pos[l]+1;i<pos[r];i++) lazy[i]+=c;//中间完整区间处理
}
int main(){
    scanf("%d",&n);
    k=sqrt(n);//每k个数分1块
    int sum=n/k+(n%k!=0);//共分sum个块
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) pos[i]=(i-1)/k+1;//每个数在哪个块
    for(int i=1;i<=sum;i++) L[i]=(i-1)*k+1,R[i]=i*k;//左右端点
    R[sum]=n;
    for(int i=1;i<=n;i++){
        int opt,l,r,c;
        scanf("%d%d%d%d",&opt,&l,&r,&c);
        if(opt==0) add(l,r,c);
        else if(opt==1) printf("%d\n",a[r]+lazy[pos[r]]);
    }
    return 0;
}

[知识学习] 分块

原文:https://www.cnblogs.com/Xx-queue/p/12193193.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!