• ST表


    ST表

    部分内容来自:
    https://blog.csdn.net/xuechen_gemgirl/article/details/77073979?ops_request_misc={"request_id"%3A"158265901119725222458250"%2C"scm"%3A"20140713.130056874.."}&request_id=158265901119725222458250&biz_id=0&utm_source=distribute.pc_search_result.none-task

    特点##

    1.用来维护静态区间最值非常有效快捷的方法

    2.它与DP类似,具有后无效性,层次关系之间具有最优性

    复杂度:预处理:O(nlogn),单次查询O(1),空间O(nlogn)

    (对比隔壁线段树:预处理O(nlogn),查询O(logn),空间O(n))

    具体操作##

    更新###

    用二维数组a[m][i]来记录包含m这个点以m为左(或右)端点区间长为2^i个数的最优值

    那么类似于dp,他也有类似的转移关系式(这里默认m为右端点)

    a[m][i]=opt(a[m][i-1]+a[m-(1<<(i-1))][i-1](注意别忘了给位运算加小括号)

    既然m左边的ST值已经确定,那么维护a[m][i]无非只需要让i不断++直到越左边界为止

    查询###

    查询的过程无非就是给定区间段[x,y],如下图所示

    那么就需要注意一个点就是如何确定两个已定区间,使得他们的并集刚好为[x,y]

    因为ST表中存储的区间宽度是2^k,所以我们计算出int lenl=log(len)/log(2),使得左、右区间长度各位2^len1,这样一定可以使得查询区间全覆盖,取max(左,右)即是答案。

    例题##

    1.洛谷P1198

    题意:就是一个序列你可以往后插入一定值或者查询从后往前数K个数内最优值

    分析:在插入数时,前面序列的性质是不变,我们只需要维护插入位置m的对应的ST值,即a[m][i]

    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define INF 1e10+5
    #define MAXN 200005
    #define MINN -105
    typedef long long int LL;
    int a[MAXN][20];
    int m=0;
    LL D;
    LL max(LL a,LL b)
    {
        return a>b?:a,b;
    }
    LL check_opt(LL len)
    {
        int k=log(len)/log(2);
        return max(a[m][k],a[m-len+(1<<k)][k]);
    }
    void insert_renew()
    {
        for(int i=1;m-(1<<i)>=0;i++)
            a[m][i]=max(a[m][i-1],a[m-(1<<(i-1))][i-1]);
    }
    int main()
    {
    	LL n,cur,t=0;
    	memset(a,0,sizeof(a));
    	char aaa;
    	 cin>>n>>D;
    for(int i=0;i<n;i++)
    {
        cin>>aaa>>cur;
        if(aaa=='Q')
        {
            cur=check_opt(cur);
            cout<<cur<<endl;
            t=cur;
        }
        else
        {
            m++;
            a[m][0]=(cur+t)%D;
            insert_renew();
        }
    }
    return 0;
    }
  • 相关阅读:
    java基础
    Java开发环境搭建
    打开CMD的方式和常用的Dos命令
    电脑常用快捷键
    Markdown学习
    c# json object Dictionary互转
    dapper 跨表查询
    Dapper SimpleCRUD Demo
    c#中的常用ToString()方法总结
    android js 模拟键盘
  • 原文地址:https://www.cnblogs.com/et3-tsy/p/12441019.html
Copyright © 2020-2023  润新知