①一维RMQ

(1) dp[i,j] 表示从第i个数起连续2j个数中的(最大值min、最小值max、最大公约数gcd……),通过更改下列代码中的红色函数即可实现。

(2) b数组放置所需查询的数列。

  1. const int MAX=;
  2. int dp[MAX][];
  3. int mm[MAX];
  4. void initrmq(int n,int b[])
  5. {
  6. mm[]=-;
  7. for(int i=;i<=n;i++)
  8. {
  9. mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
  10. dp[i][]=b[i];
  11. }
  12. for(int j=;j<=mm[n];j++)
  13. for(int i=;i+(<<j)-<=n;i++)
  14. dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
  15. }
  16. ll rmq(int x,int y)
  17. {
  18. int k=mm[y-x+];
  19. return max(dp[x][k],dp[y-(<<k)+][k]);
  20. }

②二维RMQ

给定一个n*m矩阵,每次询问左上角(r1,c1)到右下角(r2,c2)的子矩形中的(最大值min、最小值max、最大公约数gcd……)并输出。如果每次所询问的四个角有符合条件的数,输出yes,否则输出no。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<map>
  6. using namespace std;
  7. typedef long long ll;
  8. const int MAX=;
  9. int val[MAX][MAX];
  10. int dp[MAX][MAX][][];//最大值
  11. int mm[MAX];
  12. void initRMQ(int n,int m)//m*n的矩阵
  13. {
  14. for(int i=;i<=n;i++)
  15. for(int j=;j<=m;j++)
  16. dp[i][j][][]=val[i][j];
  17. for(int ii=;ii<=mm[n];ii++)
  18. for(int jj=;jj<=mm[m];jj++)
  19. if(ii+jj)
  20. for(int i=;i+(<<ii)-<=n;i++)
  21. for(int j=;j+(<<jj)-<=m;j++)
  22. if(ii)dp[i][j][ii][jj]=max(dp[i][j][ii-][jj],dp[i+(<<(ii-))][j][ii-][jj]);
  23. else dp[i][j][ii][jj]=max(dp[i][j][ii][jj-],dp[i][j+(<<(jj-))][ii][jj-]);
  24. }
  25. int rmq(int x1,int y1,int x2,int y2)//所查询矩形区间内的最大值 左上角(x1,y1) -> 右上角(x2,y2)
  26. {
  27. int k1=mm[x2-x1+];
  28. int k2=mm[y2-y1+];
  29. x2=x2-(<<k1)+;
  30. y2=y2-(<<k2)+;
  31. return max(max(dp[x1][y1][k1][k2],dp[x1][y2][k1][k2]),max(dp[x2][y1][k1][k2],dp[x2][y2][k1][k2]));
  32. }
  33. int main()
  34. {
  35. mm[]=-;
  36. for(int i=;i<=MAX;i++)
  37. mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
  38. int n,m,Q;
  39. int r1,c1,r2,c2;
  40. while(scanf("%d%d",&n,&m)==)
  41. {
  42. for(int i=;i<=n;i++)
  43. for(int j=;j<=m;j++)
  44. scanf("%d",&val[i][j]);
  45. initRMQ(n,m);
  46. scanf("%d",&Q);
  47. while(Q--)
  48. {
  49. scanf("%d%d%d%d",&r1,&c1,&r2,&c2);//左上角(r1,c1) -> 右上角(r2,c2)
  50. if(r1>r2)swap(r1,r2);
  51. if(c1>c2)swap(c1,c2);
  52. int tmp=rmq(r1,c1,r2,c2);
  53. printf("%d ",tmp);
  54. if(tmp==val[r1][c1]||tmp==val[r1][c2]||tmp==val[r2][c1]||tmp==val[r2][c2])
  55. printf("yes\n");
  56. else printf("no\n");
  57. }
  58. }
  59. return ;
  60. }

③二维RMQ降维

给定一个n*n(n<=500)的矩阵(即是正方形),每次询问以(x,y)为左上角,边长为s的正方形区域内的最大值。

dp[i][j][k]:以(i,j)为左上角,边长为2^k的正方形区域内的最大值。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cmath>
  5. using namespace std;
  6. typedef long long ll;
  7. const int MAX=;
  8. int dp[MAX][MAX][],mm[MAX],val[MAX][MAX];
  9. void initrmq(int n)
  10. {
  11. int lt,lb,rt,rb;
  12. for(int k=;k<=mm[n];k++)
  13. for(int i=;i+(<<k)-<=n;i++)
  14. for(int j=;j+(<<k)-<=n;j++)
  15. if(k==)
  16. dp[i][j][k]=val[i][j];
  17. else
  18. {
  19. lt=dp[i][j][k-]; //左上角
  20. lb=dp[i+(<<k-)][j][k-]; //左下角
  21. rt=dp[i][j+(<<k-)][k-]; //右上角
  22. rb=dp[i+(<<k-)][j+(<<k-)][k-];//右下角
  23. dp[i][j][k]=max(max(lt,lb),max(rt,rb));
  24. }
  25. }
  26. int rmq(int x,int y,int s)
  27. {
  28. if(s==)return val[x][y];
  29. int k=mm[s];
  30. int lt=dp[x][y][k];
  31. int lb=dp[x+s-(<<k)][y][k];
  32. int rt=dp[x][y+s-(<<k)][k];
  33. int rb=dp[x+s-(<<k)][y+s-(<<k)][k];
  34. return max(max(lt,lb),max(rt,rb));
  35. }
  36. int main()
  37. {
  38. int i,j,k,T;
  39. mm[]=-;
  40. for(i=;i<=MAX;i++)
  41. mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
  42. scanf("%d",&T);
  43. for(int cas=;cas<=T;cas++)
  44. {
  45. int n,q;
  46. scanf("%d%d",&n,&q);
  47. for(i=;i<=n;i++)
  48. for(j=;j<=n;j++)
  49. scanf("%d",&val[i][j]);
  50. initrmq(n);
  51. printf("Case %d:\n",cas);
  52. while(q--)
  53. {
  54. int x,y,s;
  55. scanf("%d%d%d",&x,&y,&s);
  56. printf("%d\n",rmq(x,y,s));
  57. }
  58. }
  59. return ;
  60. }

【模板】RMQ(计算区间最值)的更多相关文章

  1. ST表 求 RMQ(区间最值)

    RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...

  2. 【RMQ】 区间最值查询详解

    1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A ...

  3. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  4. 基于稀疏表(Sparse Table)的RMQ(区间最值问题)

    在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...

  5. 【模板】 RMQ求区间最值

    RMQ RMQ简单来说就是求区间的最大值(最小值) 核心算法:动态规划 RMQ(以下以求最大值为例) F[i,j]表示 从 i 开始 到i+2j -1这个区间中的最大值 状态转移方程 F[i,j]=m ...

  6. RMQ求区间最值 nlog(n)

    转载于:http://blog.csdn.net/xuzengqiang/article/details/7350465 RMQ算法全称为(Range Minimum/Maximum Query)意思 ...

  7. RMQ算法区间最值

    问题类型:是多次询问一个大区间里子区间的最值问题 dp + 位运算的思想处理 rmax[i][j]表示从i开始到i + 2^j - 1的区间里的最大值dp[i][j] ==== (i,i + 2^j ...

  8. HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)

    HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...

  9. RMQ(模板 ST 区间最值,频繁的间隔时间)

    PS: 介绍:http://blog.csdn.net/liang5630/article/details/7917702 RMQ算法.是一个高速求区间最值的离线算法,预处理时间复杂度O(n*log( ...

随机推荐

  1. 转动的八卦图纯css实现

      这类的东西网上一搜就是大把的,看着比较空旷的博客,所以自己也来写一个. <!DOCTYPE html> <html> <head> <meta chars ...

  2. 1-3 Sass 语法、编译、调试

    Sass 语法格式 这里说的 Sass 语法是 Sass 的最初语法格式,他是通过 tab 键控制缩进的一种语法规则,而且这种缩进要求非常严格.另外其不带有任何的分号和大括号.常常把这种格式称为 Sa ...

  3. Django—XSS及CSRF

    一.XSS 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻击者往W ...

  4. apk下载安装,存储的位置,路径

    PackageInstaller 原理简述 应用安装是智能机的主要特点,即用户可以把各种应用(如游戏等)安装到手机上,并可以对其进行卸载等管理操作.APK是Android Package的缩写,即An ...

  5. Hush Framework框架配置(转)

    在写这篇文章的时候,楼主已经饿的不行了,因为我从3点开始就在折腾Hush Framework,走了很多弯路,打铁要趁热,先把基本的过程记录下来,留待以后翻阅,同时记录其中容易走弯路的地方,特别是对于一 ...

  6. qwewq

  7. ES6/ES2015常用知识点和概念

    越来越多的开源库开始使用ES2015来构建代码了,大家知道ES6=ES2015,ES6在2015年被ECMAScript标准化组织approve,各大浏览器厂商要完全支持ES6的强大功能还须一些时日, ...

  8. SQLServer 2008 新增T-SQL 简写语法

    1.定义变量时可以直接赋值 DECLARE @Id int = 5 2.Insert 语句可以一次插入多行数据 INSERT INTO StateList VALUES(@Id, 'WA'), (@I ...

  9. DEV控件之ChartControl用法 z

    一.总体概述 这个控件包含3层,最外面的chartControl层.中间的XYDiagram层.最里面的Series层.功能非常强大,但同时使用起来也相对复杂,需要各个层之间相互协调设置才能达到自己想 ...

  10. 运维不仅仅是懂Linux就行,还需要知道这些……

    运维不仅仅是懂Linux就行,因为还有一大部分的Windows运维,最近看一个报道说,windows的服务器占了47.71%.嗯,向windows运维人员致敬.当然我们这篇文章不是说运维除了懂Linu ...