POJ2019

我们其实是很有必要把ST算法拓展到二维的,因为二维的RMQ问题还是不少的

int N,B,K;
int mm[];
int val[maxn][maxn];
int dpmin[maxn][maxn][][];
int dpmax[maxn][maxn][][];

这里的N是方阵的长宽,此处是正方形题目,然后mm是预处理出来的,方便计算指数

dpmin和dpmax就是预处理数组了

然后看一下开局预处理:

void initRMQ(int n,int m)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
dpmin[i][j][][]=dpmax[i][j][][]=val[i][j];
for(int ii=;ii<=mm[n];ii++)
for(int jj=;jj<=mm[m];jj++)
if(ii+jj)
for(int i=;i+(<<ii)-<=n;i++)
for(int j=;j+(<<jj)-<=m;j++)
{
if(ii)
{
dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-][jj],dpmin[i+(<<(ii-))][j][ii-][jj]);
dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-][jj],dpmax[i+(<<(ii-))][j][ii-][jj]);
}
else
{
dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-],dpmin[i][j+(<<(jj-))][ii][jj-]);
dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-],dpmax[i][j+(<<(jj-))][ii][jj-]);
}
}
}

我们看预处理的时候还是比较明朗的,当然别忘了在主函数把mm初始化好

    mm[]=-;
for(int i=;i<=;i++)
mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];

然后就是求最大值和最小值的函数了,这里,一定要仔细地去写,很容易写错:

int rmq1(int x1,int y1,int x2,int y2)  //max
{
int k1=mm[x2-x1+];
int k2=mm[y2-y1+];
x2=x2-(<<k1)+;
y2=y2-(<<k2)+;
return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));
}
int rmq2(int x1,int y1,int x2,int y2)
{
int k1=mm[x2-x1+];
int k2=mm[y2-y1+];
x2=x2-(<<k1)+;
y2=y2-(<<k2)+;
return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));
}

这个式子确实很长的

最后给出题目完整的实现:

 #include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
int N,B,K;
int mm[];
int val[maxn][maxn];
int dpmin[maxn][maxn][][];
int dpmax[maxn][maxn][][];
void initRMQ(int n,int m)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
dpmin[i][j][][]=dpmax[i][j][][]=val[i][j];
for(int ii=;ii<=mm[n];ii++)
for(int jj=;jj<=mm[m];jj++)
if(ii+jj)
for(int i=;i+(<<ii)-<=n;i++)
for(int j=;j+(<<jj)-<=m;j++)
{
if(ii)
{
dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-][jj],dpmin[i+(<<(ii-))][j][ii-][jj]);
dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-][jj],dpmax[i+(<<(ii-))][j][ii-][jj]);
}
else
{
dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-],dpmin[i][j+(<<(jj-))][ii][jj-]);
dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-],dpmax[i][j+(<<(jj-))][ii][jj-]);
}
}
}
int rmq1(int x1,int y1,int x2,int y2) //max
{
int k1=mm[x2-x1+];
int k2=mm[y2-y1+];
x2=x2-(<<k1)+;
y2=y2-(<<k2)+;
return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));
}
int rmq2(int x1,int y1,int x2,int y2)
{
int k1=mm[x2-x1+];
int k2=mm[y2-y1+];
x2=x2-(<<k1)+;
y2=y2-(<<k2)+;
return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));
}
int main()
{
mm[]=-;
for(int i=;i<=;i++)
mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
while(scanf("%d%d%d",&N,&B,&K)==)
{
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
scanf("%d",&val[i][j]);
initRMQ(N,N);
int x,y;
while(K--)
{
scanf("%d%d",&x,&y);
printf("%d\n",rmq1(x,y,x+B-,y+B-)-rmq2(x,y,x+B-,y+B-));
}
}
return ;
}

数据结构:二维ST表的更多相关文章

  1. BZOJ3577:玩手机(最大流,二维ST表)

    Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...

  2. BZOJ1047[HAOI2007]理想的正方形——二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...

  3. 【CodeForces】713 D. Animals and Puzzle 动态规划+二维ST表

    [题目]D. Animals and Puzzle [题意]给定n*m的01矩阵,Q次询问某个子矩阵内的最大正方形全1子矩阵边长.n,m<=1000,Q<=10^6. [算法]动态规划DP ...

  4. 【洛谷 P2216】 [HAOI2007]理想的正方形(二维ST表)

    题目链接 做出二维\(ST\)表,然后\(O(n^2)\)扫一遍就好了. #include <cstdio> #include <cstring> #include <a ...

  5. Codeforces 713D Animals and Puzzle(二维ST表+二分答案)

    题目链接 Animals and Puzzle 题意  给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...

  6. [模板]二维ST表

    考试yy二维ST表失败导致爆零. 其实和一维的ST表很像... 也是设$f[i][j][p][q]$为以$(i, j)$为左上角,长为$2^p$,宽为$2^q$的矩形的最大值. 算法流程是先把每一行都 ...

  7. [HNOI2007] 理想正方形 二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...

  8. 模板 - 数据结构 - ST表 + 二维ST表

    区间最大值,$O(nlogn)$ 预处理,$O(1)$ 查询,不能动态修改.在查询次数M显著大于元素数量N的时候看得出差距. 令 $f[i][j]$ 表示 $[i,i+2^j-1]$ 的最大值. 显然 ...

  9. [总结] 二维ST表及其优化

    二维 \(\mathcal{ST}\) 表,可以解决二维 \(\mathcal{RMQ}\) 问题.这里不能带修改,如果要修改,就需要二维线段树解决了. 上一道例题吧 ZOJ2859 类比一维 \(\ ...

随机推荐

  1. javascript打开新窗口

    一.window.open()支持环境: JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+ 二.基本语法: window.open(pageURL,name, ...

  2. java连接数据库的两种方法总结

    方法一:使用jdbc-odbc桥连接sql server,作为中间媒介连接数据库 1.配置数据源:打开控制面版->管理工具->数据源(ODBC)->选用户DSN,按下添加按钮-> ...

  3. ACM 第十一天

    多校7题目 GuGuFishtion Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  4. python学习笔记03:python的核心数据类型

    从根本上讲,Python是一种面向对象的语言.它的类模块支持多态,操作符重载和多重继承等高级概念,并且以Python特有的简洁的语法和类型,OOP十分易于使用.Python的语法简单,容易上手. Py ...

  5. TCP系列15—重传—5、Linux中RTO的计算

    之前我们介绍的都是协议中给出的RTO计算方法,下面我们看一下linux实现中RTO的计算方法.在linux中维护了srtt.mdev.mdev_max.rttvar.rtt_seq几个状态变量用来计算 ...

  6. 【APS.NET Core】- 应用程序Startup类介绍

    转自:https://www.cnblogs.com/stulzq/p/7845026.html Startup类配置服务和应用程序的请求管道. Startup 类 ASP.NET Core应用程序需 ...

  7. PHP实现大文件分割上传与分片上传

    转载:http://www.zixuephp.com/phpstudy/phpshilie/20170829_43029.html 服务端为什么不能直接传大文件?跟php.ini里面的几个配置有关 u ...

  8. [OS] 操作系统常考知识点

    转自:http://jennica.space/2017/03/21/os-principle/ 大纲如下: 1.操作系统概述2.操作系统运行环境3.进程线程模型4.处理器调度5.同步机制6.存储模型 ...

  9. sql 插入列放第一列

    如果是SQLSERVER 的话就这样:select * from dbo.syscolumns where id=OBJECT_ID(N'你的表名') 然后COLID这列就是列的顺序 修改这个字段就行 ...

  10. asp.net mvc4中Json的应用

    做一个简单的 Json实例,从页面获取后台的Json数据 1.控制台: public class HomeController : Controller { // // GET: /Home/ pub ...