zoukankan      html  css  js  c++  java
  • luogu P3865 【模板】ST表

    luogu P3865 【模板】ST表

    利用递推解决区间最值问题

    建成后,不支持修改区间上某一点的值

    建表O(nlogn),查询O(1)

    1<< t == 二的 t 次方

    p[ k ][ i ]==从 i 开始包括 i 长为 2^k 的区间的最值

    p[ 0 ][ i ]即为 a[ i ]的值本身

    1.建表时

        区间[ i , i + 2^k -1 ] 最值等于区间[ i , i +2( k-1 )-1 ]与区间 [ i +2( k -1) ][ i + 2^k -1]的最值

    p[k][i]=max(p[k-1][i],p[k-1][i+(1<<(k-1))])

        最开始知道所有的 p[ 0 ][ i ],用 p[ 0 ][ i ]去推 p[ 1 ][ i ]直到到 p[ t ][ i ]

    2.询问时

        区间[ l ,r ]最值等于区间[ l , l +2^k -1]与区间[ r -2^k +1 , r ]的最值

        由于k 取log2( r - l +1)向下取整,p[ k ][ l ]与p[ t ][ r – (1 << t) + 1]取最值返回

        2^(k+1)一定能包含整个区间[ l ,r ],所以这两个 P 数组所代表的区间,一定会覆盖所求区间,且不会越界

    #include<cstdio>
    #include<cmath>      //log2()函数需调用<cmath>
    #include<iostream>   //max,min,swap调用<iostream>
    using namespace std;
    int n,m;
    int p[50][100001],a[100001];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) p[0][i]=a[i];
        int t=log2(n);
        for(int k=1;k<=t;k++)   //建表
            for(int i=1;i+(1<<k)-1<=n;i++)
                p[k][i]=max(p[k-1][i],p[k-1][i+(1<<(k-1))]);int l,r;
        for(int i=1;i<=m;i++)   //询问
        {
            scanf("%d%d",&l,&r);
            t=log2(r-l+1);
            printf("%d
    ",max(p[t][l],p[t][r-(1<<t)+1]));
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 3390 Bad Cowtractors牛的报复
    BZOJ 4291 Kieszonkowe
    【重温基础】3.循环和迭代
    【重温基础】3.循环和迭代
    【重温基础】2.流程控制和错误处理
    【重温基础】2.流程控制和错误处理
    【重温基础】1.语法和数据类型
    【重温基础】1.语法和数据类型
    vue axios全攻略
    vue axios全攻略
  • 原文地址:https://www.cnblogs.com/QAQq/p/10301856.html
Copyright © 2011-2022 走看看