ST表专题总结

ST表(sparse table)用于静态RMQ问题,建表复杂度O( nlogn ),区间询问复杂度O(1)。文章通过例题NO.1(A Magic Lamp HDU - 3183)和NO.2(AraBellaC HDU - 6387)详细讲解了ST表的使用,包括贪心解法和ST表优化算法,涉及字符串处理和循环节构建。
摘要由CSDN通过智能技术生成

ST表专题总结

ST表(sparse table):用于静态RMQ(Range Minimum/Maximun Query)问题,不适用于带有修改操作的RMQ问题(要用线段树)。
ST表的建表复杂度为 O( nlogn ), 区间询问复杂度为O(1)。
学习网址 http://www.360doc.com/content/19/0406/15/5315_826796736.shtml

ST表常规模板:

#include <bits/stdc++.h>
#define ll long long
#define mem( f, x ) memset( f, x, sizeof( f ))
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define mk(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
const int N = 1e4 + 5;
const int M = 21;
int m, n;
int lg[N];
int f[N][M];

int Max( int x, int y ){
   
    return x>y ? x:y;
}

void st( ){
   
    for( int i = 1; i <= 21; i++ ){
   
        for( int j = 1; j + ( 1<<i ) -1 <= n; j++ )
            f[j][i] = Max( f[j][i-1], f[j+(1<<(i-1))][i-1] );
    }
}

int query( int l, int r ){
   
    int k = lg[r-l+1];
    return Max( f[l][k], f[r-(1<<k)+1][k] );  //f[r-(1<<k)+1][k]:已知右端点r和区间长度1<<k,则左端点为r-(1<<k)+1
}

int main( ){
   
    while( scanf( "%d %d", &n, &m ) != EOF ){
   
        lg[0] = -1;
        for( int i = 1; i <= n; i++ ){
   
            lg[i] = lg[i/2] + 1; //底数为2的logn取整技巧
            scanf( "%d", *f[i] );
        }
        while( m-- ){
   
            int l, r;
            scanf( "%d %d", &l, &r );
            printf( "%d\n", query( l, r ) );
        }
    }
    return 0;
}

例题讲解:

NO.1

A Magic Lamp HDU - 3183
题意: 给你一串长度为n的数字串,要求删掉m个字符数后剩下的字符所所形成的数字最小,其中 m <= n <= 1000。

错解: 去掉最大的m个字符。
反例: 17082 m = 1
很明显去掉7所得到的1082比去掉8所得到的1702要小

解法一:
贪心解法:假设删去s[i],则s[i]要满足从前往后遍历第一个满足s[i] > s[i+1],
暴力遍历,复杂度O(n^2)完全可以接受。

解法二:
考虑一位一位取n-m位数,第一位数肯定在s[1…m+1]中选取,因为若是从下标大于m+1的字符中选取则后面剩余的字符必然小于n-m-1,最终不足以凑成n-m个字符,选取的标准为s[1…m+1]中最小的字符。同样选取第二个字符时的范围为s[i+1…m+2],其中i为上一次(这里指第一次)选取的字符下标,至于

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值