zoukankan      html  css  js  c++  java
  • [ST表]

    P3865

    [模板]ST表

    题目大意:求[L,R]静态区间最大值

    做法:

    1:定义:(f[i][j])表示([i,i+2^{j}−1])这段长度为(2^{j})的区间中的最大值。

    2:(RMQ)问题:给定一个长度为(N)的区间,(M)个询问,每次询问([L_i,R_i])这段区间元素的最大值/最小值。(RMQ)的高级写法一般有两种,即为线段树和(ST)表。本文主要讲解一下(ST)表的写法。(以区间最大值为例)ST表:一种利用(dp)思想求解区间最值的倍增算法。

    3:预处理:(f[i][0] = a[i])。即([i,i])区间的最大值(a_i)

    4:状态转移:将([i,j])分成两段,设(k=log_2^{j-i+1}),一段为([i,i+2^{k}−1]),另一段为([j-2^k+1,j])。两段的长度均为(2^{k})([i,j])的最大值即这两段的最大值中的最大值。

    #include<cmath>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 1e5+6;
    int n,m,a[maxn],f[maxn][21];
    
    void RMQ(int n)
    {
        for(int j=1;j<=20;j++)
            for(int i=1;i<=n && i+(1<<j-1)<=n;i++)
                f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]); 
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		f[i][0] = a[i];
    	}
        RMQ(n);
        for(int i=1;i<=m;i++)
    	{
            int L,R;
            scanf("%d%d",&L,&R);
            int k = (int)(log((double)(R - L + 1)) / log(2.0));// 保证 可以覆盖到i - j全部 数值 2^( 
    		printf("%d
    ",max(f[L][k],f[R - (1 << k) + 1][k]));
    	}
        return 0;
    }
    
  • 相关阅读:
    shiro角色与权限
    shiro Realm体系
    shiro AuthenticationToken体系
    shiro身份认证流程
    git相关
    Logback 快速入门 / 使用详解
    SLF4J 快速入门 / 绑定原理
    Java 日志框架概述(slf4j / log4j / JUL / Common-logging(JCL) / logback)
    Java 浮点数精确性探讨(IEEE754 / double / float)与 BigDecimal 解决方案
    Maven 快速入门
  • 原文地址:https://www.cnblogs.com/-Wind-/p/11857581.html
Copyright © 2011-2022 走看看