• ST表(RMQ) 总结


    f[i][j] 表示 以i号点为起点 的长度为 2^j 次方 终点为i+2^j-1 的最大或者最小值

    打表时间复杂度 O(Nlog2(N)) 查询O(1)

    打表代码:

    for(int i=1;i<=n;i++) 
        {
            scanf("%d",&f[i][0]);
        }
        for(int j=1;j<=log2(n);j++)
        {
            for(int i=1;i+(1<<j)-1<=n;i++)
            {
                f[i][j]=max(f[i][(j-1)],f[i+(1<<j-1)][j-1]);
            }
        }

    将区间分为两段 [i ,i+2^(j-1)-1 ] 和[2^(j-1)+i,i+2^j-1]

    查询代码:

            scanf("%d%d",&l,&r);
            int k=log2(r-l+1);
            printf("%d
    ",max(f[l][k],f[r-(1<<k)+1][k]));

    k 为区间长度的log2 值  查询 l到l+2^k-1 和r-(2^k)+1 到 r

    关于二维 RMQ 

    查询一个矩阵里面的最大最小值

     例题 POJ https://vjudge.net/problem/POJ-2019

    code:

    //
    #include<iostream>
    #include<cstdio>
    #include<cmath> 
    using namespace std;
    int f1[260][260][40],f2[260][260][40];
    int n,b,kk;
    int RMQ(int x,int y,int c)
    {
        int k=log2(c);
        int xx=x+c-1;
        int yy=y+c-1;
        int i=x,j=y;
        int t1=min(f2[i][j][k],f2[xx-(1<<k)+1][j][k]);
        t1=min(t1,min(f2[xx-(1<<k)+1][yy-(1<<k)+1][k],f2[i][yy-(1<<k)+1][k]));
        int t2=max(f1[xx-(1<<k)+1][yy-(1<<k)+1][k],f1[i][yy-(1<<k)+1][k]);
        t2=max(max(f1[i][j][k],f1[xx-(1<<k)+1][j][k]),t2);
        return t2-t1;
        
    }
    int main()
    {
        scanf("%d%d%d",&n,&b,&kk);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&f1[i][j][0]);
                f2[i][j][0]=f1[i][j][0];
            }
        for(int k=1;k<=log2(n);k++)
        {
            for(int i=1;i+(1<<k)-1<=n;i++)
                for(int j=1;j+(1<<k)-1<=n;j++)
                {
                    int t1=min(f2[i][j][k-1],f2[i+(1<<k-1)][j][k-1]);
                    int t2=min(f2[i][j+(1<<k-1)][k-1],f2[i+(1<<k-1)][j+(1<<k-1)][k-1]);
                    f2[i][j][k]=min(t1,t2);
                     t1=max(f1[i][j][k-1],f1[i+(1<<k-1)][j][k-1]);
                     t2=max(f1[i][j+(1<<k-1)][k-1],f1[i+(1<<k-1)][j+(1<<k-1)][k-1]);
                    f1[i][j][k]=max(t1,t2);
                }
        }
        int x,y;
        while(kk--)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",RMQ(x,y,b));
        }
    }
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    Ajax和Jsonp的工作原理,以及区别。
    git与GitHub
    Cookie的作用以及封装的方法
    关于angular-route后获取路由标签的一些问题
    javascriptDOM节点
    字符串转化为对象的方法
    将"goOd gooD stUdy dAy dAy up"每个单词的首字母转换成大写其余还是小写字母
    利用HashSet对list集合去重
    集合之Iterator迭代器
    java常用API之System类
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11330747.html
Copyright © 2020-2023  润新知