RMQ模板题 poj3368

在线算法,预处理O(n*log n),询问 O(1)

第一次学RMQ做的模板题。。。注意f【】数组保存的值,所以询问L,R的时候知道L和前面的值不一样再进行询问

另外切开k的位置不需要计算那块有多少连续的,因为f【k】的值本身就记录了。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
#define FOR(i, l, r) for(int i = l; i <= r; i++)
#define REP(i, r, l) for(int i = r; i >= l; i--)
typedef long long ll;
double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
int a[100010];
int f[100010];
int d[100010][20];
int n;
void init()
{
    FOR(i,1,n)
        d[i][0]=f[i];
    for(int j=1; (1<<j) <=n; j++)
        for(int i=0; i + (1<<j) -1 <= n;i++ )
            d[i][j]=max( d[i][j-1], d[ i+(1<<(j-1))][j-1]);

}
int rmq(int l,int r)
{
    if(l>r) return 0;
    int k=0;
    while( (1<<(k+1)) <= r-l+1)
        k++;
    int ans=max( d[l][k] ,d[r-(1<<k)+1][k]);
    
    return  ans ;
}
int main()
{
    while(~scanf("%d",&n))
    {
        if(n == 0) break;
        memset(a,0,sizeof(a));
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        int m;
        scanf("%d",&m);
        FOR( i, 1, n)
            scanf("%d",&a[i]);
        f[1] = 1;
        FOR( i, 2, n){
            if(a[i] == a[i-1])
                f[i] = f[i-1]+1;
            else f[i] = 1;
        }
        init();
        while(m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            
            int t=l;
            while(t<=r && a[t] == a[t-1])
                t++;
            int ans=rmq( t, r);
            ans =max(ans, t-l);
            printf("%d\n",ans);
        }
        
    }
    return 0;
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值