ST表模板

```
//ST表模板 


//预处理 O(nlogn),处理O(1),空间O(nlogn)。


#include<iostream>
using namespace std;
const int N = 100006;
int dp[N][25];   //区间最小值 
int mn[N];      //存储分割点 
int a[N];       //存储数据 
int n;
/*dp公式
 例dp[5][3] = min(dp[5][2],dp[9][2]);
等价于min(5,12) = min(min(5...8),min(9...12));
又例min(5,14) = min(min(5...12),min(13...14))
= min(min(5...8),min(9...12),min(13...14)
= min(min(5...6),min(7...8),min(9...10),min(11...12),min(13...14);
    等价于min(dp[5][3],dp[13][1]);
特例min(5,15)= min(dp[5][3],dp[12][2]);
= min(min(5...12),min(12...15));
dp[x][y],左端点为x,右端点为x+2^y-1 */
void init()
{
    for(int i=1; i<=n; i++)
        dp[i][0] = a[i]; 
    for(int j=1; (1<<j)<=n; j++)
        for(int i=1; i+(1<<j)-1<=n; i++)
            dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    for(int len=1;len<=n;++len)
    {
        int k = 0;
        while((1<<(k+1))<=len)
            k++;
        mn[len] = k;
    }
}
int rmq(int L,int R)
{
    int k=mn[R-L+1];
    return min(dp[L][k],dp[R-(1<<k)+1][k]);
}
int main()
{
    int m;  cin >> n >> m;
    for(int i=1; i<=n; i++)     cin >> a[i];
    init();
    for(int i=0; i<m; i++)
    {
        int l,r;        cin >> l >> r;
        cout << rmq(l,r) << endl;
    }
    return 0;
 }

“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值