• 算法笔记--st表


    概述:用倍增法求区间最值的离线算法,O(nlogn)预处理,O(1)访问。

    预处理:

      状态:st[i][j]:[i,i+2^j)之间的最值  

      状态转移:如果j等于0,st[i][j]=a[i]

           如果j大于0,st[i][j]=max(st[i][j-1],st[i+2^(j-1)][j-1])或st[i][j]=min(st[i][j-1],st[i+2^(j-1)][j-1])

    访问:

      求[l,r]区间里的最值

      k=floor(log(r-l+1))

      ans=max(st[l][k],st[r-2^k+1][k])或ans=min(st[l][k],st[r-2^k+1][k])

    模板:

    int st[N][20],a[N];
    void init_st(int n){
        for(int i=n;i>=1;i--){
            st[i][0]=a[i];
            for(int j=1;i+(1<<j-1)-1<=n;j++){
                st[i][j]=min(st[i][j-1],st[i+(1<<j-1)][j-1]);
            }
        }
    }
    int query(int l,int r){
        int k=floor(log(r-l+1)/log(2));
        return min(st[l][k],st[r-(1<<k)+1][k]);
    }

     例题:POJ - 3264

    思路:求区间最值差

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    int ss[N][20],st[N][20],a[N];
    void init_st(int n){
        for(int i=n;i>=1;i--){
            st[i][0]=a[i];
            ss[i][0]=a[i];
            for(int j=1;i+(1<<j-1)-1<=n;j++){
                st[i][j]=min(st[i][j-1],st[i+(1<<j-1)][j-1]);
                ss[i][j]=max(ss[i][j-1],ss[i+(1<<j-1)][j-1]);
            }
        }
    }
    int query(int l,int r){
        int k=floor(log(r-l+1)/log(2));
        return max(ss[l][k],ss[r-(1<<k)+1][k])-min(st[l][k],st[r-(1<<k)+1][k]);
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,q,l,r;
        cin>>n>>q;
        for(int i=1;i<=n;i++)cin>>a[i];
        init_st(n);
        while(q--){
            cin>>l>>r;
            cout<<query(l,r)<<endl;
        }
        return 0;
    }
    View Code

    参考:https://www.cnblogs.com/AireenYe/p/6270518.html

  • 相关阅读:
    软件测试工具
    Linux笔记
    Google Test
    字典dict()
    元组tuple 可迭代对象
    列表list
    一些总结
    format()
    列表list
    format() expandtabs() 输入表格数据
  • 原文地址:https://www.cnblogs.com/widsom/p/8320838.html
Copyright © 2020-2023  润新知