【算法每日一练]-结构优化(保姆级教程 篇6 分块,倍增)#HDU4417超级马里奥 #poj2019玉米田 #POJ3368频繁值

今天知识点:

区间统计不超过h的值;

查询二维区间的极差;

求区间最频繁数;

目录

HDU4417:超级马里奥

思路:

poj2019:玉米田

思路:

POJ3368:频繁值

思路:


        

        

HDU4417:超级马里奥

在长n的道路中。每个i点都有高度Hi的砖,输入l,r,h表示他最高能跳h,问在区间[l,r]中最多可以跳多少砖块?

输入:
1                              
10 10                       
0 5 2 7 5 4 3 8 7 7 
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3

输出:

Case1:

4 0 0 3 1 2 0 1 5 1

        

思路:

其实就是统计区间中有多少个不超过h的值。

我们采用分块处理,对于完整的块,可以采用排序,然后upper_bound直接返回个数。不完整的块暴力所查区间

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int L[maxn],R[maxn],be[maxn];
int a[maxn],tmp[maxn],n,m;void build(){int t=sqrt(n);int num=n/t;if(n%num)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<=n;i++){be[i]=(i-1)/t+1;}for(int i=1;i<=num;i++){sort(tmp+L[i],tmp+1+R[i]);//每块排序}
}int query(int l,int r,int h){int ans=0;if(be[l]==be[r]){//在同一块就暴力for(int i=l;i<=r;i++)if(a[i]<=h)ans++;}else{for(int i=l;i<=R[be[l]];i++){//左端块暴力if(a[i]<=h)ans++;}for(int i=be[l]+1;i<be[r];i++){//中间块直接lowerboundans+=upper_bound(tmp+L[i],tmp+R[i]+1,h)-tmp-L[i];//直接获取能跳过去的个数}for(int i=L[be[r]];i<=r;i++){//右端块暴力if(a[i]<=h) ans++;}}return ans;
}
int main(){int t;cin>>t;for(int cas=1;cas<=t;cas++){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);tmp[i]=a[i];}build();printf("Case %d:\n",cas);while(m--){int l,r,h;scanf("%d%d%d",&l,&r,&h);printf("%d\n",query(++l,++r,h));}}
}

        

        

poj2019:玉米田

为了寻找平坦的地来种玉米,在n*n公顷的农场中,每公顷都有一个整数高度,查询k次,对于(x,y)为左顶点的c*c子矩阵中的最大和最小高度差是多少?

输入:
5 3 1
5 1 2 6 3
1 3 5 2 7
7 2 4 6 1
9 9 8 6 5
0 6 9 3 9
1 2

        

思路:

首先这题是个离线的区间最值题,倍增就行了

一维max不满足减法,所以不能直接建立二维max数组,那么就用多个一维的max数组等价成二维的即可。

但是我们仍然开三维数组f[x][y][j]表示(x,y)点向右扩展1<<j长度的最值

因为每次查询都要取一次log,当查询量较大时候就不行了,所以可以利用动态规划来初始化log函数因为如果i&(i-1)是0,那么log(i)=log(i-1)+1,否则log(i)=log(i-1)。

void initlog(){b[0]=-1;for(int i=1;i<maxn;i++){b[i]=(i&(i-1))?b[i-1]:b[i-1]+1;}
}
#include <bits/stdc++.h>
using namespace std;
const int maxn=260;
int a[maxn][maxn],b[maxn];
int f_max[maxn][maxn][11],f_min[maxn][maxn][11];//f[x][y][j]表示(x,y)点向右扩展1<<j长度的最值void initlog(){b[0]=-1;for(int i=1;i<maxn;i++){b[i]=(i&(i-1))?b[i-1]:b[i-1]+1;}
}void ST(int n){for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)f_max[k][i][0]=f_min[k][i][0]=a[k][i];//初始化for(int k=1;k<=n;k++)//一行一行处理for(int j=1;j<=b[n];j++)//j是二进制大小for(int i=1;i+(1<<j)-1<=n;i++){//i是每个列值f_max[k][i][j]=max(f_max[k][i][j-1],f_max[k][i+(1<<(j-1))][j-1]);//更新最大值和最小值f_min[k][i][j]=min(f_min[k][i][j-1],f_min[k][i+(1<<(j-1))][j-1]);}
}void solve(int x,int y,int c){//从(x,y)开始向右下扩展c长度int k=b[c];int maxx=-1,minx=0x3f3f3f3f;int l=y,r=y+c-1;for(int i=x;i<x+c;i++){//查询每行的最值maxx=max(maxx,max(f_max[i][l][k],f_max[i][r-(1<<k)+1][k]));minx=min(minx,min(f_min[i][l][k],f_min[i][r-(1<<k)+1][k]));}printf("%d\n",maxx-minx);
}int main(){int n,k,c;int x,y;initlog();while(scanf("%d%d%d",&n,&c,&k)!=EOF){//输入n大小,c大小,k次数for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);ST(n);for(int i=0;i<k;i++){scanf("%d%d",&x,&y);solve(x,y,c);}}
}

        

        

POJ3368:频繁值

给定一个非递减的整数序列n,进行q次查询,确定i到j之间的最频繁的值
10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10
0
输出

4
3

 

思路:

注意到非递减的性质,不难想到对应的频繁数1 2 1 2 3 4 1 1 2 3然后就转化成了离线的区间最值。

直接设置f[i][j]表示存放[i,i+2^j-1]长度2^j的最值,初始化f[i][0],然后在查询区间的时候注意单独处理最左边的元素,剩余的区间就能直接查询了

#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
int a[maxn],b[maxn],f[maxn][20];//a存放数据,b存放log值,f存放[i,i+2^j-1]长度2^jvoid initlog(){b[0]=-1;for(int i=1;i<maxn;i++){b[i]=(i&(i-1))?b[i-1]:b[i-1]+1;}
}void ST(int n){for(int j=1;j<=b[n];j++){for(int i=1;i<=n-(1<<j)+1;i++){f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);}}
}int RMQ(int l,int r){if(l>r)return 0;int k=b[r-l+1];return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){int n,q,l,r;initlog();while(~scanf("%d",&n)&&n){cin>>q;for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(i==1){ //初始化过程f[i][0]=1;continue;}if(a[i]==a[i-1]){f[i][0]=f[i-1][0]+1;}else f[i][0]=1;	}ST(n);for(int j=1;j<=q;j++){scanf("%d%d",&l,&r);int t=l;while(t<=r&&a[t]==a[t-1]) t++;//将查询区间分开printf("%d\n",max(t-l,RMQ(t,r)));}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/219477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言之文件操作(上)

C语言之文件操作&#xff08;上&#xff09; 文章目录 C语言之文件操作&#xff08;上&#xff09;1. 什么是⽂件&#xff1f;1.1 程序⽂件1.2 数据⽂件1.3 ⽂件名 2. ⼆进制⽂件和⽂本⽂件3. ⽂件的打开和关闭3.1 流和标准流3.1.1 流3.1.2 标准流 4. ⽂件指针5. 文件的打开与关…

【广州华锐视点】物流数字孪生三维可视化系统打造更高效、智能的物流管理体验

在当今快速发展的物流行业中&#xff0c;传统的管理和监控方法往往难以满足复杂运营的需求。为了解决这个问题&#xff0c;广州华锐互动提供物流数字孪生三维可视化系统定制开发服务&#xff0c;打造更为高效、智能的物流管理体验。 物流数字孪生三维可视化系统是一种基于虚拟现…

虚拟现实三维电子沙盘数字沙盘开发教程第5课

虚拟现实三维电子沙盘数字沙盘无人机倾斜摄影全景建模开发教程第5课 设置system.ini 如下内容 Server122.112.229.220 userGisTest Passwordchinamtouch.com 该数据库中只提供 成都市火车南站附近的数据请注意&#xff0c;104.0648,30.61658 在鼠标指定的位置增加自己的UI对象&…

【Hive】——DDL(CREATE TABLE)

1 CREATE TABLE 建表语法 2 Hive 数据类型 2.1 原生数据类型 2.2 复杂数据类型 2.3 Hive 隐式转换 2.4 Hive 显式转换 2.5 注意 3 SerDe机制 3.1 读写文件机制 3.2 SerDe相关语法 3.2.1 指定序列化类&#xff08;ROW FORMAT SERDE ‘’&#xff09; 3.2.2 指定分隔符&#xff0…

深入理解Dubbo-8.Dubbo的失败重试设计

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

鸿蒙(HarmonyOS)北向开发项目编译问题汇总

运行Hello World Hello World 工程可以运行在模拟器中&#xff0c;或者运行在真机设备中。本示例先以选择将 Hello World 工程运行在模拟器中进行说明&#xff0c;如果选择运行在真机设备中&#xff0c;需要先对工程进行签名&#xff0c;然后才能运行在真机设备中。 DevEco S…

[数据集][目标检测]芝麻杂草目标检测数据集VOC+YOLO格式1300张2类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1300 标注数量(xml文件个数)&#xff1a;1300 标注数量(txt文件个数)&#xff1a;1300 标注类别数&a…

从零到一:influxdb时序性数据库的基本概念与操作指南

目录 ​编辑 引言 数据库(database) 创建数据库 删除数据库 进入数据库 展示influxdb中所有数据库 测量&#xff08;measurement&#xff09; 写入测量 展示测量 总结 引言 InfluxDB是一个开源的时序数据库&#xff0c;专门设计用于处理时间序列数据。它是由InfluxD…

C# 两个日期比较大小

文章目录 C# 两个日期比较大小直接比较大小工具类DateTime.Compare C# 两个日期比较大小 直接比较大小 string ed "2023-12-13 09:27:59.000";//过去式DateTime nowDateTime DateTime.Now;DateTime expirationDate Convert.ToDateTime(ed);//质保期 长日期DateT…

一行奇异代码,解决transition过渡动画无效问题!

一行奇异代码&#xff0c;解决transition过渡动画无效问题&#xff01; 无效的transition过渡动画 你是否遇到过这种情况&#xff1a;在css中设置了transition过渡动画&#xff0c;但使用时&#xff0c;确无效。 例如以下代码&#xff0c;便是一例&#xff1a; 在此代码中&a…

【云原生kubernets】Service 的功能与应用

一、Service介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。为了解决这个问题&#xff0c;kubernetes提供了Service资…

慎用,Mybatis-Plus这个方法可能导致死锁

1 场景还原 1.1 版本信息 MySQL版本&#xff1a;5.6.36-82.1-log Mybatis-Plus的starter版本&#xff1a;3.3.2 存储引擎&#xff1a;InnoDB1.2 死锁现象 A同学在生产环境使用了Mybatis-Plus提供的 com.baomidou.mybatisplus.extension.service.IService#saveOrUpdate(T, co…

Linux下常用的工具软件

这里我会为大家介绍Linux世界里最常用的几种工具软件&#xff0c;包括&#xff1a;vi, tar, gzip, rpm。 1.文字编辑 vi是Linux(UNIX)世界最强大的文本编辑工具&#xff0c;我在第一讲中提到过它&#xff0c;现在我把它的一些基本使用方法介绍给大家。 Vi的三种状态 Comman…

Linux中使用podman管理容器

本章主要介绍使用podman管理容器 了解什么是容器&#xff0c;容器和镜像的关系安装和配置podman拉取和删除镜像给镜像打标签导出和导入镜像创建和删除镜像数据卷的使用管理容器的命令使用普通用户管理容器 对于初学者来说&#xff0c;不太容易理解什么是容器&#xff0c;这里…

挑战与创新:光学字符识别技术在处理复杂表格结构中的应用

OCR&#xff08;Optical Character Recognition&#xff09;光学字符识别技术是指通过计算机软硬件将印刷或手写的字符转化为可编辑和搜索的文本。这项技术已经被广泛应用于各个领域&#xff0c;例如扫描文档、自动化数据输入、图书数字化等。但是&#xff0c;当涉及到处理复杂…

利用websockify将websocket通信转换成tcp

文章目录 前言websockifywebsockify 介绍websockify 使用 探索的过程提供基础TCP服务测试可用 实现Websocket客户端开始测试websockify功能再次启动websockify单独实现一个js版本websocket客户端 什么是VNC总结 前言 目前遇到一个问题&#xff0c;原本的服务都是利用tcp通信的…

​glob --- Unix 风格路径名模式扩展​

源代码: Lib/glob.py glob 模块会按照 Unix shell 所使用的规则找出所有匹配特定模式的路径名称&#xff0c;但返回结果的顺序是不确定的。 波浪号扩展不会生效&#xff0c;但 *, ? 以及用 [] 表示的字符范围将被正确地匹配。 这是通过配合使用 os.scandir() 和 fnmatch.fnmat…

“ABCD“[(int)qrand() % 4]作用

ABCD[(int)qrand() % 4] 作用 具体来说&#xff1a; qrand() 是一个函数&#xff0c;通常在C中用于生成一个随机整数。% 4 会取 qrand() 生成的随机数除以4的余数。因为4只有四个不同的余数&#xff08;0, 1, 2, 3&#xff09;&#xff0c;所以这实际上会生成一个0到3之间的随…

java方法引用语法规则以及简单案例

目录 一、方法引用1.1 什么是方法引用1.2 方法引用的语法规则1.3 构造器引用1.4 方法引用的简单案例 参考资料 一、方法引用 1.1 什么是方法引用 方法引用是 Lambda 表达式的一种简写形式&#xff0c;用于表示已有方法的直接引用。 类似于lambda表达式&#xff0c;方法引用也…

window系统使用ESP8266开发板(CP2102)

连接开发板到电脑 虚拟机中选择连接的开发板硬件 查看设备管理器 更新驱动: CP210x USB to UART Bridge VCP Drivers - Silicon Labs 驱动安装成功