分块 学习笔记

分块学习笔记

1)设置块的大小

sn=(int)sqrt(n);
if(n/sn>=MX) sn=n/MX;//MX为块的极限大小,若卡空间时用,这时数组与块数量有关的部分可以开小,与块大小有关的部分则要开大,注意。。

2)方便的函数

int loc(int x){//位置x属于哪一块
    return x/sn +1;//返回+1是空出第0块来,搞前缀和不用特判什么的
}

int getL(int x){//第x块左端点
    return max((x-1)*sn,1);//最左是1,要取max
}

int getR(int x){
    return min(x*sn-1,n);//最右是n,要取min
}

3)预处理信息

1)前缀块信息,每块n个信息$n\sqrt n $
2)块到块信息,每块\(\sqrt n\)个信息$(\sqrt n)^3=n\sqrt n $
3)所某块的左端点到右边任意位置的信息,$n\sqrt n $
这个最好开$\sqrt n *\sqrt n \(数组,每块留一个0的空位,最后留一个sn的位置记整块总和 **可以\)O(\sqrt n)\(维护\)O(1)$询问解决单点修改区间查询问题**

4)获得答案

BL,BR表示第BL块-第BR块
L,R表示BL块的左端点及BR块的右端点
x, y为询问区间

BL=loc(x),BR=loc(y);
if(BL+1>=BR){//x,y在同一块/相邻两块直接扫过去统计
    for(i=x;i<=y;i++) xxx;
}
else{
    if(getL(BL)!=x) BL++;
    if(getR(BR)!=y) BR--;
    L=getL(BL);
    R=getR(BR);
    ans+=get(BL,BR);
    for(i=x;i<L;i++) xxx;
    for(i=y;i>r;i++) xxx;
}

5) 注意事项:

预处理数组时注意 初始化

转载于:https://www.cnblogs.com/acha/p/6437312.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值