zoukankan      html  css  js  c++  java
  • 数据结构:二维ST表

    POJ2019

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

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

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

    dpmin和dpmax就是预处理数组了

    然后看一下开局预处理:

    void initRMQ(int n,int m)
    {
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dpmin[i][j][0][0]=dpmax[i][j][0][0]=val[i][j];
        for(int ii=0;ii<=mm[n];ii++)
        for(int jj=0;jj<=mm[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)
            {
                dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-1][jj],dpmin[i+(1<<(ii-1))][j][ii-1][jj]);
                dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-1][jj],dpmax[i+(1<<(ii-1))][j][ii-1][jj]);
            }
            else
            {
                dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-1],dpmin[i][j+(1<<(jj-1))][ii][jj-1]);
                dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-1],dpmax[i][j+(1<<(jj-1))][ii][jj-1]);
            }
        }
    }

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

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

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

    int rmq1(int x1,int y1,int x2,int y2)  //max
    {
        int k1=mm[x2-x1+1];
        int k2=mm[y2-y1+1];
        x2=x2-(1<<k1)+1;
        y2=y2-(1<<k2)+1;
        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+1];
        int k2=mm[y2-y1+1];
        x2=x2-(1<<k1)+1;
        y2=y2-(1<<k2)+1;
        return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));
    }

    这个式子确实很长的

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

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=255;
     5 int N,B,K;
     6 int mm[505];
     7 int val[maxn][maxn];
     8 int dpmin[maxn][maxn][8][8];
     9 int dpmax[maxn][maxn][8][8];
    10 void initRMQ(int n,int m)
    11 {
    12     for(int i=1;i<=n;i++)
    13     for(int j=1;j<=m;j++)
    14         dpmin[i][j][0][0]=dpmax[i][j][0][0]=val[i][j];
    15     for(int ii=0;ii<=mm[n];ii++)
    16     for(int jj=0;jj<=mm[m];jj++)
    17     if(ii+jj)
    18     for(int i=1;i+(1<<ii)-1<=n;i++)
    19     for(int j=1;j+(1<<jj)-1<=m;j++)
    20     {
    21         if(ii)
    22         {
    23             dpmin[i][j][ii][jj] = min(dpmin[i][j][ii-1][jj],dpmin[i+(1<<(ii-1))][j][ii-1][jj]);
    24             dpmax[i][j][ii][jj] = max(dpmax[i][j][ii-1][jj],dpmax[i+(1<<(ii-1))][j][ii-1][jj]);
    25         }
    26         else
    27         {
    28             dpmin[i][j][ii][jj] = min(dpmin[i][j][ii][jj-1],dpmin[i][j+(1<<(jj-1))][ii][jj-1]);
    29             dpmax[i][j][ii][jj] = max(dpmax[i][j][ii][jj-1],dpmax[i][j+(1<<(jj-1))][ii][jj-1]);
    30         }
    31     }
    32 }
    33 int rmq1(int x1,int y1,int x2,int y2)  //max
    34 {
    35     int k1=mm[x2-x1+1];
    36     int k2=mm[y2-y1+1];
    37     x2=x2-(1<<k1)+1;
    38     y2=y2-(1<<k2)+1;
    39     return max(max(dpmax[x1][y1][k1][k2],dpmax[x1][y2][k1][k2]),max(dpmax[x2][y1][k1][k2],dpmax[x2][y2][k1][k2]));
    40 }
    41 int rmq2(int x1,int y1,int x2,int y2)
    42 {
    43     int k1=mm[x2-x1+1];
    44     int k2=mm[y2-y1+1];
    45     x2=x2-(1<<k1)+1;
    46     y2=y2-(1<<k2)+1;
    47     return min(min(dpmin[x1][y1][k1][k2],dpmin[x1][y2][k1][k2]),min(dpmin[x2][y1][k1][k2],dpmin[x2][y2][k1][k2]));
    48 }
    49 int main()
    50 {
    51     mm[0]=-1;
    52     for(int i=1;i<=500;i++)
    53         mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
    54     while(scanf("%d%d%d",&N,&B,&K)==3)
    55     {
    56         for(int i=1;i<=N;i++)
    57         for(int j=1;j<=N;j++)
    58             scanf("%d",&val[i][j]);
    59         initRMQ(N,N);
    60         int x,y;
    61         while(K--)
    62         {
    63             scanf("%d%d",&x,&y);
    64             printf("%d
    ",rmq1(x,y,x+B-1,y+B-1)-rmq2(x,y,x+B-1,y+B-1));
    65         }
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    html使用网络图片防盗问题解决
    【HC89S003F4开发板】 8c转义成汇编工程
    【HC89S003F4开发板】 7ASM&C混合编程
    【HC89S003F4开发板】 2调度器
    jquery 基础
    React 中import时如何正确使用花括号'{ }',以及default,export的用法注意事项
    React的小知识点
    TCP建立连接三步握手
    pdo操作基础
    php -- 取路径:getcwd()、__DIR__、__FILE__ 的区别【转】
  • 原文地址:https://www.cnblogs.com/aininot260/p/9379833.html
Copyright © 2011-2022 走看看