首页 > 其他分享 >RMQ模板整理

RMQ模板整理

时间:2023-02-07 12:01:41浏览次数:51  
标签:RMQ k2 int ii x2 dmin 整理 dmax 模板


查询区间的最大最小值,属于离线做法,主要运用倍增+DP思想。

参考书籍:算法进阶指南

一维RMQ

查询区间最大值或最小值

//求最大值,数组下标从1开始。

//求最小值,或者最大最小值下标,或者数组从0开始对应修改即可。

const int MAXN = 50010;

int dp[MAXN][20];

int mm[MAXN];

// 初始化RMQ,b数组下标从1开始,b数组是区间元素序列

void initRMQ(int n, int b[])

{

mm[0] = -1;

for (int i = 1; i <= n; i++)

{

mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1];

dp[i][0] = b[i];

}

for (int j = 1; j <= mm[n]; j++)

{

for (int i = 1; i + (1 << j) - 1 <= n; i++)

{

dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);

}

}

}



// 查询最大值

int rmq(int x, int y)

{

int k = mm[y - x + 1];//int k= (int)(log((r - l + 1) * 1.0) / log(2.0));

return max(dp[x][k], dp[y - (1 << k) + 1][k]);

}

二维RMQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int MAXN=255;
int val[MAXN][MAXN];
int dmin[MAXN][MAXN][8][8];
int dmax[MAXN][MAXN][8][8];
void initRMQ(int n,int m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dmin[i][j][0][0]=dmax[i][j][0][0]=val[i][j];
for(int ii=0;(1<<ii)<=n;ii++)
for(int jj=0;(1<<jj)<=m;jj++)
if(ii+jj)
for(int i=1;i+(1<<ii)-1<=n;i++)
for(int j=1;j+(1<<jj)-1<=m;j++)
if(ii)
{
dmin[i][j][ii][jj] = min(dmin[i][j][ii-1][jj] ,dmin[i+(1<<(ii-1))][j][ii-1][jj]);
dmax[i][j][ii][jj] = max(dmax[i][j][ii-1][jj] ,dmax[i+(1<<(ii-1))][j][ii-1][jj]);
}
else
{
dmin[i][j][ii][jj] = min(dmin[i][j][ii][jj-1] , dmin[i][j+(1<<(jj-1))][ii][jj-1]);
dmax[i][j][ii][jj] = max(dmax[i][j][ii][jj-1] , dmax[i][j+(1<<(jj-1))][ii][jj-1]);
}
}
int getMax(int x1,int y1,int x2,int y2)
{
int k1=0;
while((1<<(k1+1))<=x2-x1+1)k1++;
int k2=0;
while((1<<(k2+1))<=y2-y1+1)k2++;
x2 = x2 - (1<<k1)+1;
y2 = y2 - (1<<k2)+1;
return max(max(dmax[x1][y1][k1][k2],dmax[x1][y2][k1][k2]) ,max(dmax[x2][y1][k1][k2],dmax[x2][y2][k1][k2]) );
}
int getMin(int x1,int y1,int x2,int y2)
{
int k1=0;
while((1<<(k1+1))<=x2-x1+1)k1++;
int k2=0;
while((1<<(k2+1))<=y2-y1+1)k2++;
x2 = x2 - (1<<k1)+1;
y2 = y2 - (1<<k2)+1;
return min( min(dmin[x1][y1][k1][k2],dmin[x1][y2][k1][k2]) ,min(dmin[x2][y1][k1][k2],dmin[x2][y2][k1][k2]) );
}

int main()
{
int n,b,k;
while(scanf("%d%d%d",&n,&b,&k)==3&&n&&b&&k)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&val[i][j]);
initRMQ(n,n);
while(k--)
{
int a,e;
scanf("%d%d",&a,&e);
int maxx= getMax(a,e,a+b-1,e+b-1);
int minn= getMin(a,e,a+b-1,e+b-1);
cout<<maxx-minn<<endl;
}
}
return 0;
}

 

标签:RMQ,k2,int,ii,x2,dmin,整理,dmax,模板
From: https://blog.51cto.com/u_14932227/6041861

相关文章

  • AcWing整数二分算法模板
    原链接boolcheck(intx){/*...*/}//检查x是否满足某种性质//区间[l,r]被划分成[l,mid]和[mid+1,r]时使用:intbsearch_1(intl,intr){while(l<r......
  • 类模板与板书对象2
    #include<iostream>#include<vector>#include<algorithm>usingnamespacestd;template<typenamenumberType>structIsMultiple{numberTypem_Divisor;//几的......
  • 【Appium】python利用Template生成对象模板_appium_元素定位/操作
    UI自动化中用PageObject设计模式就会发现page元素定位代码基本重复,复制黏贴,修改,所以就想到运用模板方式,批量生成page,同理也能批量生成handle。有模板,利用配置文件ini获取......
  • 模板模式
    /*模板模式:解决某类事情的步骤有些是固定的,有些是会发生变化的,那么这时候我们可以为这类事情提供一个模板代码,从而提高效率。需求;编写一个计算程序运行时间的模板。模板......
  • 批量通过模板打印
    模版表名Templatesheet25数据列表名sheet1打印程序SubPrintLabel()WithThisWorkbook.Sheets("Sheet1")limitmax=.Range("B10000").End(xlUp).Row......
  • 全流程搞清楚 Kubernetes API 的使用,可进行业务二次开发对接 k8s 调用,详细图文说明以
    全流程搞清楚KubernetesAPI的使用,可进行业务二次开发对接k8s调用,详细图文说明以及常见问题整理。使用CLI(如curl)或GUI(如postman)HTTP客户端调用KubernetesAPI有很多理由......
  • 常用插件整理 之《React》
    状态管理ReduxJavaScript状态容器,提供可预测化的状态管理ReduxThunkRedux的异步处理中间件MobX通过函数响应式编程使得状态管理变得简单和可扩展Dva一......
  • CSS 3 所有的选择器整理(2023.2)
    你知道的和你不知道的所有选择器。不包含尚未广泛实现的,也不包含已弃用的。基本的选择器规则(Selector)类型(Type)选择器直接用标签匹配特定的元素span{ ...}p{ .........
  • ES Monitoring 整理笔记
    Monitoring是elasticstack的监控模块,监控信息存在es索引中,并且可以通过kibana进行可视化的展示。(收集监控数据的方式从6.5版本起由Collectors-Exporters模式逐步迁移到使......
  • 整理我遇到的 Python 的疑难问题
    1如果字典里一个键指向一个实例,深拷贝会拷贝出一个新的实例吗?不会:classfoo:def__init__(self):print('doinitfoo')a={'cls':foo()}a#......