当前位置: 首页 > article >正文

【算法每日一练]-分块(保姆级教程 篇1)POJ3648

插讲一下分块

        

        

题目:(POJ 3648) 一个简单的整数问题

        

        

前缀和往往用于静态的不会修改的区间和。遇到经常修改的区间问题,就要用分块或线段树来维护了。

分块算法是优化后的暴力,分块算法有时可以维护一些线段树维护不了的东西,虽然效率一般不如线段树,但是比线段树更易上手。

         

         

分块算法分3步骤:

        

1,预处理块:处理块长(往往是根号n),每块的左右下标L[], R[],每块的区间和suf[],每个元素所属的块号pos[]

        

2,区间修改:对于完整的块仅修改懒标记,不完整的就暴力修改a[]和suf[]

        

3,区间查询 :对于完整的块直接利用懒和suf,不完整的就暴力

        

#include <bits/stdc++.h>//POJ3648
using namespace std;
const int N=100010;
typedef long long ll;
ll a[N],suf[N],add[N];
int L[N],R[N],pos[N];
int n,m,t,l,r,d;
char op[3];
//分块预处理:(我们处理下标都是从1开始)
void build(){//处理t块长,L[]R[]每块的左右下标,pos[]每个下标的所属块号,suf[]每块的和
	t=sqrt(n*1.0);
	int num=n/t;
	if(n%t) num++;
	for(int i=1;i<=num;i++){
		L[i]=(i-1)*t+1;
		R[i]=i*t;
	}
	R[num]=n;//更改最后一块的右下标
	for(int i=1;i<=num;i++){
		for(int j=L[i];j<=R[i];j++){
			pos[j]=i;
			suf[i]+=a[j];
		}
	}
}
//区间修改
void change (int l,int r,ll d){//修改add[]懒标,a[]和suf[]
	int p=pos[l],q=pos[r];
	if(p==q){//如果在同一块就暴力修改a[]和suf[]
		for(int i=l;i<=r;i++) a[i]+=d;
		suf[p]+=d*(r-l+1);
	}
	else{//完整的块仅修改懒标,不完整就暴力
		for(int i=p+1;i<=q-1;i++) add[i]+=d;
		for(int i=l;i<=R[p];i++) a[i]+=d;
		suf[p]+=d*(R[p]-l+1);
		for(int i=L[q];i<=r;i++) a[i]+=d;
		suf[q]+=d*(r-L[q]+1);
	}
}

ll query(int l,int r){
	int p=pos[l],q=pos[r];
	ll ans=0;
	if(p==q){//同一块就暴力
		for(int i=l;i<=r;i++) ans+=a[i];
		ans+=add[p]*(r-l+1);
	}
	else{//完整就suf+add,不完整就暴力
		for(int i=p+1;i<=q-1;i++) ans+=suf[i]+add[i]*(R[i]-L[i]+1);
		for(int i=l;i<=R[p];i++) ans+=a[i];
		for(int i=L[q];i<=r;i++) ans+=a[i];
		ans+=add[q]*(r-L[q]+1);
	}
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build();
	for(int i=1;i<=m;i++){
		scanf("%s %d %d",op,&l,&r);
		if(op[0]=='C'){
			scanf("%d",&d);
			change(l,r,d);
		}
		else{
			printf("%lld\n",query(l,r));
		}
	}
}

 


http://www.kler.cn/news/133677.html

相关文章:

  • 百胜杯答题系统
  • 公网访问全能知识库工具AFFINE,Notion的免费开源替代
  • 【hive遇到的坑】—使用 is null / is not null 对string类型字段进行null值过滤无效
  • C++ 虚函数和多态性
  • React整理总结(三)
  • 公司内部网络架设悟空CRM客户管理系统 cpolar无需公网IP实现内网,映射端口外网访问
  • 【测开求职】面试题:HR面相关的开放性问题
  • 基于Prometheus快速搭建网络质量监控平台
  • 2023_“数维杯”问题B:棉秸秆热解的催化反应-详细解析含代码
  • 计算机毕业设计选题推荐-点餐微信小程序/安卓APP-项目实战
  • Java Web——JavaScript基础
  • 高防IP是什么?如何隐藏源站IP?如何进行防护?
  • 代码随想录二刷 | 数组 | 总结篇
  • 03 前后端数据交互【小白入门SpringBoot + Vue3】
  • wpf devexpress在未束缚模式中生成Tree
  • IDEA写mybatis程序,java.io.IOException:Could not find resource mybatis-config.xml
  • 单元测试实战(六)其它
  • 【HarmonyOS开发】设备调试避坑指南
  • 三十一、W5100S/W5500+RP2040树莓派Pico<TCP_Server多路socket>
  • 别再吐槽大学教材了,来看看这些网友强推的数学神作!
  • 【我和Python算法的初相遇】——体验递归的可视化篇
  • SQL note2:DIsks and Files
  • linux如何一键自动安装系统(PXE)
  • 03_面向对象高级_多态
  • C++11的互斥包装器
  • 怎样助力IT运维团队更专业、更协作、更高效
  • 详解如何使用Jenkins一键打包部署SpringBoot项目
  • 华媒舍:怎样成为谷歌竞价排名羸家?10个方法
  • HIT 模式识别 手写汉字分类 Python实现
  • 038、语义分割